Redis集群与spring的整合

傷城~ 2022-07-13 02:15 265阅读 0赞

上一篇详细的赘述了Redis的curd操作及集群的搭建。下面我们开始将他整合到我们实际的项目中去。我的项目采用的是标准的ssm框架,ssm框架这里不说,直接开始整合。

  • 首先在maven管理中将我们的jar包引入


    org.springframework.data
    spring-data-redis
    1.7.2.RELEASE



    redis.clients
    jedis
    2.9.0
  • 在spring配置文件中我们可以进行配置Redis,但是为了将Redis分离容易修改我将它卸载另外一个xml文件中,只要在spring配置文件中引入这个Redis配置文件就行了。

这里写图片描述

  • 下面所有的记录都是在Redis这个配置文件进行操作的。

Redis连接池配置

  • 这里只是将设置连接池的一些基本属性,比如说最大连接数,连接前属性判断等






  • maxIdle:控制一个pool最多有多少个状态为idle的jedis实例;

  • 在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的
  • maxWaitMillis : 表示当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;

Redis集群配置

这里我们就是将我们上一篇开启的Redis服务引入到项目中来。clusterNodes就是我们一个一个的Redis服务。

  1. <!-- Redis集群配置 -->
  2. <bean id="redisClusterConfig" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
  3. <property name="maxRedirects" value="3"></property>
  4. <property name="clusterNodes">
  5. <set>
  6. <bean class="org.springframework.data.redis.connection.RedisNode">
  7. <constructor-arg name="host" value="127.0.0.1"></constructor-arg>
  8. <constructor-arg name="port" value="7000"></constructor-arg>
  9. </bean>
  10. <bean class="org.springframework.data.redis.connection.RedisNode">
  11. <constructor-arg name="host" value="127.0.0.1"></constructor-arg>
  12. <constructor-arg name="port" value="7004"></constructor-arg>
  13. </bean>
  14. <bean class="org.springframework.data.redis.connection.RedisNode">
  15. <constructor-arg name="host" value="127.0.0.1"></constructor-arg>
  16. <constructor-arg name="port" value="7005"></constructor-arg>
  17. </bean>
  18. </set>
  19. </property>
  20. </bean>

Redis连接工厂

我们将上面的Redis服务节点和连接池引入到工厂中,有工程去生产一个可用的jedis提供我们进行缓存的CURD操作!!

  1. <!-- ReDis连接工厂 -->
  2. <bean id="redis4CacheConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
  3. <constructor-arg name="clusterConfig" ref="redisClusterConfig" />
  4. <property name="timeout" value="${redis.timeout}" />
  5. <property name="poolConfig" ref="redisPoolConfig" />
  6. </bean>

Redis模板

提供了jedis进行操作我们就要放道模板里面给我们调用!。

  1. <!-- 存储序列化 -->
  2. <bean name="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
  3. <!-- 集群Resis使用模板 -->
  4. <bean id="clusterRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
  5. <property name="connectionFactory" ref="redis4CacheConnectionFactory" />
  6. <property name="keySerializer" ref="stringRedisSerializer" />
  7. <property name="hashKeySerializer" ref="stringRedisSerializer" />
  8. <property name="valueSerializer" ref="stringRedisSerializer" />
  9. <property name="hashValueSerializer" ref="stringRedisSerializer" />
  10. </bean>

项目调用

在配置文件中都已经将jedis配置好了,我们只需要通过这个模板就可以对Redis进行CURD操作了。下面是个简单的列子

  1. clusterRedisTemplate.execute(new RedisCallback<Long>() {
  2. public Long doInRedis(RedisConnection connection)
  3. throws DataAccessException {
  4. byte[] keyb = key.getBytes();
  5. byte[] valueb = toByteArray(value);
  6. // 判断当前值是否已经存在
  7. if (connection.exists(keyb)) {
  8. // 删除原数据
  9. connection.del(keyb);
  10. }
  11. connection.set(keyb, valueb);
  12. return 1L;
  13. }
  14. });

源码探究竟

在RedisClusterConfiguration类中我们传入的Redis服务node,我们设置的是property然后该类中就开始执行下面代码
这里写图片描述

然后我们在工厂中传入这些节点,

这里写图片描述

这个工厂给我提供了一个afterproperties方法,意思就是在这些参数设置完成之后执行的一个方法。

这里写图片描述

在这里我们可以看见一个creatPool的方法,这个就是去连接池里创建连接
这里写图片描述

Bug解决

上面的部署 会出现一个问题,就是在项目中,每次初始化时会重连接池中选择一个可用的Redis服务连接,当这个Redis服务宕机后我们的项目还会继续连接这个Redis服务,我们只能从新启动项目,项目才会从新从连接池中选择新的Redis服务。

  • 解决办法 我在每次操作Redis时都去重构连接池,这样就保证我每次都会去连接池找一个正真可用的Redis服务。
  • 解决就是将RedisNode注入到项目中,每次都执行我们上次看到的creatPool方法

    /* Redis模板注入 /

    1. @Resource
    2. private RedisClusterConfiguration redisClusterConfig;
    3. private JedisConnectionFactory redis4CacheConnectionFactory;
    4. @Resource
    5. private RedisTemplate<String, Object> clusterRedisTemplate;
    6. //重构连接池
    7. private void init(){
    8. redis4CacheConnectionFactory=new JedisConnectionFactory(redisClusterConfig);
    9. redis4CacheConnectionFactory.afterPropertiesSet();
    10. clusterRedisTemplate.setConnectionFactory(redis4CacheConnectionFactory);
    11. }

这样又出现问题了,每次都初始化连接池,这在连接池上很费性能,暂时没有解决办法,但是我初步想通过redis sentinel 来检测Redis集群中的Redis服务。当Redis宕机后通过sentinel 提供的API来通知项目重新去构建连接池,重新连接新Redis服务

发表评论

表情:
评论列表 (有 0 条评论,265人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Redisspring整合

    上一篇详细的赘述了Redis的curd操作及集群的搭建。下面我们开始将他整合到我们实际的项目中去。我的项目采用的是标准的ssm框架,ssm框架这里不说,直接开始整合。