欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Springboot2.x.x连接Redis配置整合

程序员文章站 2022-03-26 17:07:16
目录一、必看前言对于整篇文章要解决的问题要有一个基础的认知了解springboot2.x.x各个版本存在的问题二、springboot2.x.x - lettuce连接Redis配置方式0.公共的配置文件1.springboot2.3.x-lettuce2.springboot2.2.x-lettuce3.springboot2.1.x-lettuce三、springboot2.x.x - jedis连接Redis配置方式0.公共的配置文件1.springb......

目录

一、必看前言

 对于整篇文章要解决的问题要有一个基础的认知

 了解springboot2.x.x各个版本存在的问题 

二、springboot2.x.x - lettuce连接Redis配置方式

0.公共的配置文件

1.springboot2.3.x-lettuce

2.springboot2.2.x-lettuce

3.springboot2.1.x-lettuce

三、springboot2.x.x - jedis连接Redis配置方式

0.公共的配置文件

1.springboot2.3.x-jedis & springboot2.2.x-jedis

2.springboot2.1.x-jedis


一、必看前言

 对于整篇文章要解决的问题要有一个基础的认知

1.Redis分成 单实例连接 和 集群连接 两种方式,连接方式是不一样的

2.对于两种连接方式通用的配置就是 资源池设置 和 客户端名称设置
资源池设置: 为了统一管理客户端的连接数及合理调度资源使用
客户端名称设置:
 a.当不同的项目使用同一个redis的时候,一旦redis出现了业务上的tps增长,客户端连接数增长,bigkey阻塞,如果设置了clientName可以快速的定位到是哪个连接的客户端引起的
 b.对于云部署的容器可能存在获取不到客户端的真实ip的情况,所以设置clientName是最好区分的方式

3.对于集群来说,客户端除了要维护资源池的配置还要考虑到服务端集群如果做出了更改,
客户端要及时响应刷新本地的集群信息,这就涉及到了客户端要设置redis集群的拓扑刷新问题,springboot2.x的不同版本有不同的变化刷新

4.除了以上不同springboot版本对应的redis的配置不同之外,还有一个问题就是序列化的问题,string类型的序列化就是使用string序列化的方式,
但是对于其余类型来说使用的是jdk的序列化方式,所以无论对于哪种版本我们都需要重写一下序列化方式

 了解springboot2.x.x各个版本存在的问题 

redis集群的拓扑刷新问题,只存在于lettuce的连接方式,jedis是将集群信息放入缓存中的,找不到对应的节点信息的时候会去重新获取刷新缓存,
在springboot2.3.x以后的版本添加了拓扑刷新的配置,在2.3.x之前的版本需要自己在config文件中去开启刷新

客户端名称配置,在springboot2.2.x以后的版本已经添加了配置,不需要重写配置,2.2.x之前的版本需要重写配置
版本 2.1.x-lettuce 2.2.x-lettuce 2.3.x-lettuce 2.3.x-jedis
重写拓扑 需要 需要 不需要 不需要
版本 springboot2.1.x springboot2.2.x springboot2.3.x  
clientName 需要 不需要 不需要  

 

二、springboot2.x.x - lettuce连接Redis配置方式

连接需要两个文件, application.yml 配置文件和 RedisConfig.java类,下面描述的springboot2.x.x各个版本的RedisConfig.java类的内容都是以当前的RedisConfig.java类内容为基础的.

0.公共的配置文件

/**
 * @author zcx
 */
@Configuration
public class RedisConfig {
   
    /**
     * lettuce pool springboot2.x.x 获取pool的工具类
     */
    public GenericObjectPoolConfig getGenericObjectLettucePoolConfig(RedisProperties redisProperties){
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());
        genericObjectPoolConfig.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());
        genericObjectPoolConfig.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());
        genericObjectPoolConfig.setMaxWaitMillis(redisProperties.getLettuce().getPool().getMaxWait().getSeconds());
        //默认值为false,在获取连接之前检测是否为有效连接,tps很高的应用可以使用默认值
        genericObjectPoolConfig.setTestOnBorrow(true); 
        genericObjectPoolConfig.setTestOnReturn(false);
        genericObjectPoolConfig.setTestWhileIdle(true);
        return genericObjectPoolConfig;
    }

    /**
     * 自定义序列化方式
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        // 初始化string的序列化方式
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        redisTemplate.setValueSerializer(stringRedisSerializer);
        // hash的value序列化方式采用jackson
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

1.springboot2.3.x-lettuce

application.yml

#springboot2.3.x已经添加了对于lettuce拓扑刷新的配置,也添加了对于客户端的配置
#--------------------------------springboot2.3.x lettuce配置-----------------------------------------------
spring:
  redis:
    #单实例连接打开此配置,关闭cluster配置即可
    #    host: 127.0.0.1
    #    port: 8510
    cluster:
      nodes: 127.0.0.1:6379,127.0.0.2:6379,127.0.0.3:6379,127.0.0.4:6379,127.0.0.5:6379,127.0.0.6:6379
      max-redirects: 3
    password: 123456
    timeout: 50000
    ssl: false
    database: 0
    lettuce:
      pool:
        max-active: 10
        max-idle: 8
        min-idle: 0
        max-wait: -1
      cluster:
        refresh: #拓扑刷新开关
          adaptive: true #自适应刷新集群 默认false关闭
          period: 30000 #定时刷新集群
    client-name: AppName #配置客户端名称

RedisConfig.java

/**
 * @author zcx
 */
@Configuration
public class RedisConfig {

   /**
     *  此配置添加到上边的RedisConfig.java类中
     *  springboot2.3.x 使用 lettuce 连接redis单机或集群,需要添加以下的选项
     */
    @Bean
    public RedisConnectionFactory connectionFactory(RedisProperties redisProperties) {

        //添加额外属性
        LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .poolConfig(getGenericObjectJedisPoolConfig(redisProperties))
                .clientName(redisProperties.getClientName())
                .build();

        //单机连接配置,单实例redis连接放开下边注释,同时注释掉RedisClusterConfiguration的配置
//        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisProperties.getHost(),redisProperties.getPort());
//        configuration.setPassword(redisProperties.getPassword());
        
        //集群连接配置
        RedisClusterConfiguration configuration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
        configuration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
        configuration.setPassword(RedisPassword.of(redisProperties.getPassword()));

        return new LettuceConnectionFactory(configuration, clientConfig);
    }


}

2.springboot2.2.x-lettuce

application.yml

#springboot2.2.x没有添加lettuce的拓扑刷新功能,需要通过配置文件手动添加,clientName的配置功能存在
#--------------------------------springboot2.2.x lettuce配置-----------------------------------------------
spring:
  redis:
    #单实例连接打开此配置,关闭cluster配置即可
    #    host: 127.0.0.1
    #    port: 8510
    cluster:
      nodes: 127.0.0.1:6379,127.0.0.2:6379,127.0.0.3:6379,127.0.0.4:6379,127.0.0.5:6379,127.0.0.6:6379
      max-redirects: 3
    password: 123456
    timeout: 50000
    ssl: false
    database: 0
    lettuce:
      pool:
        max-active: 10
        max-idle: 8
        min-idle: 0
        max-wait: -1
    client-name: AppName #配置客户端名称

RedisConfig.java类

/**
 * @author zcx
 */
@Configuration
public class RedisConfig {

    /**
     * 此配置添加到上边的RedisConfig.java类中
     * springboot2.2.x使用 lettuce 连接redis单实例或集群,需要添加以下的选项
     *
     * 在构建LettuceConnectionFactory时,如果不使用内置的destroyMethod,可能会导致Redis连接早于其它Bean被销毁
     */
    @Bean(destroyMethod = "destroy")
    public LettuceConnectionFactory newLettuceConnectionFactory(RedisProperties redisProperties) {
        // 配置用于开启自适应刷新和定时刷新。如自适应刷新不开启,Redis集群变更时将会导致连接异常
        ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
                .enablePeriodicRefresh(Duration.ofMinutes(10))
                .enableAllAdaptiveRefreshTriggers()
                .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(10))
                .build();
        ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()
                .topologyRefreshOptions(clusterTopologyRefreshOptions)
                .pingBeforeActivateConnection(true)
                .build();
        LettucePoolingClientConfiguration poolConfiguration = LettucePoolingClientConfiguration.builder()
                .clientOptions(clusterClientOptions)
                .clientName(redisProperties.getClientName())
                .commandTimeout(redisProperties.getTimeout())
                .poolConfig(getGenericObjectLettucePoolConfig(redisProperties))
                .build();

        //单实例连接时打开此配置,并注释下边的RedisClusterConfiguration配置
//        RedisConfiguration configuration = new
//                RedisStandaloneConfiguration(redisProperties.getHost(),redisProperties.getPort());
//        ((RedisStandaloneConfiguration) configuration).setPassword(redisProperties.getPassword());

        RedisClusterConfiguration configuration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
        configuration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
        configuration.setPassword(RedisPassword.of(redisProperties.getPassword()));

        return new LettuceConnectionFactory(configuration, poolConfiguration);
    }
}

3.springboot2.1.x-lettuce

application.yml

#springboot2.1.x没有添加lettuce的拓扑刷新功能,需要通过配置文件手动添加,也没有clientName的配置功能
#--------------------------------springboot2.2.x lettuce配置-----------------------------------------------
spring:
  redis:
    #单实例连接打开此配置,关闭cluster配置即可
    #    host: 127.0.0.1
    #    port: 8510
    cluster:
      nodes: 127.0.0.1:6379,127.0.0.2:6379,127.0.0.3:6379,127.0.0.4:6379,127.0.0.5:6379,127.0.0.6:6379
      max-redirects: 3
    password: 123456
    timeout: 50000
    ssl: false
    database: 0
    lettuce:
      pool:
        max-active: 10
        max-idle: 8
        min-idle: 0
        max-wait: -1

RedisConfig.java类

/**
 * @author zcx
 */
@Configuration
public class RedisConfig {

    /**
     * 此配置添加到上边的RedisConfig.java类中
     * springboot2.1.x使用 lettuce 连接redis单实例或集群,需要添加以下的选项
     *
     * 在构建LettuceConnectionFactory时,如果不使用内置的destroyMethod,可能会导致Redis连接早于其它Bean被销毁
     */
    @Bean(destroyMethod = "destroy")
    public LettuceConnectionFactory newLettuceConnectionFactory(RedisProperties redisProperties) {
        // 配置用于开启自适应刷新和定时刷新。如自适应刷新不开启,Redis集群变更时将会导致连接异常
        ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
                .enablePeriodicRefresh(Duration.ofMinutes(10))
                .enableAllAdaptiveRefreshTriggers()
                .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(10))
                .build();
        ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()
                .topologyRefreshOptions(clusterTopologyRefreshOptions)
                .pingBeforeActivateConnection(true)
                .build();
        LettucePoolingClientConfiguration poolConfiguration = LettucePoolingClientConfiguration.builder()
                .clientOptions(clusterClientOptions)
                //客户端名称需要在这里写死
                .clientName("AppName")
                .commandTimeout(redisProperties.getTimeout())
                .poolConfig(getGenericObjectLettucePoolConfig(redisProperties))
                .build();

        //单实例连接时打开此配置,并注释下边的RedisClusterConfiguration配置
//        RedisConfiguration configuration = new
//                RedisStandaloneConfiguration(redisProperties.getHost(),redisProperties.getPort());
//        ((RedisStandaloneConfiguration) configuration).setPassword(redisProperties.getPassword());

        RedisClusterConfiguration configuration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
        configuration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
        configuration.setPassword(RedisPassword.of(redisProperties.getPassword()));

        return new LettuceConnectionFactory(configuration, poolConfiguration);
    }
}

三、springboot2.x.x - jedis连接Redis配置方式

连接需要两个文件, application.yml 配置文件和 RedisConfig.java类,对于jedis而言,不存在redis集群的拓扑刷新问题,只是一些额外的配置随着springboot的版本不同需要添加配置文件(RedisConfig.java类)进行重写

0.公共的配置文件

RedisConfig.java类

/**
 * @author zcx
 */
@Configuration
public class RedisConfig {
   
    /**
     * jedis pool springboot2.x.x 获取pool的工具类
     * @param redisProperties
     * @return
     */
    public GenericObjectPoolConfig getGenericObjectJedisPoolConfig(RedisProperties redisProperties){
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(redisProperties.getJedis().getPool().getMaxIdle());
        genericObjectPoolConfig.setMinIdle(redisProperties.getJedis().getPool().getMinIdle());
        genericObjectPoolConfig.setMaxTotal(redisProperties.getJedis().getPool().getMaxActive());
        genericObjectPoolConfig.setMaxWaitMillis(redisProperties.getJedis().getPool().getMaxWait().getSeconds());
        //默认值为false,tps不高的时候建议开启,过高时建议关闭
        genericObjectPoolConfig.setTestOnBorrow(true);
        genericObjectPoolConfig.setTestOnReturn(false);
        genericObjectPoolConfig.setTestWhileIdle(true);
        return genericObjectPoolConfig;
    }

    /**
     * 自定义序列化方式
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        // 初始化string的序列化方式
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        redisTemplate.setValueSerializer(stringRedisSerializer);
        // hash的value序列化方式采用jackson
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

application.yml

#----------------------------------------springboot2.x.x jedis配置-------------------------------------
spring:
  redis:
#    host: 127.0.0.1
#    port: 6379
    clientName: AppName #springboot2.1.x版本没有此配置需要再RedisConfig.java类中重新写入
    cluster:
      nodes: 127.0.0.1:6379,127.0.0.2:6379,127.0.0.3:6379,127.0.0.4:6379,127.0.0.5:6379,127.0.0.6:6379
      max-redirects: 3
    password: 123456
    timeout: 50000
    ssl: false
    database: 0
    jedis:
      pool:
        max-active: 10
        max-idle: 8
        min-idle: 0
        max-wait: -1

1.springboot2.3.x-jedis & springboot2.2.x-jedis

RedisConfig.java类

/**
 * @author zcx
 */
@Configuration
public class RedisConfig {

    /**
     * springboot2.3.x  springboot2.2.x 使用 jedis 连接redis单实例或集群,需要添加以下的选项
     * 目的:为当前应用添加连接redis的标识,方便多应用连接同一个redis的问题查找
     */
    @Bean
    public RedisConnectionFactory connectionFactory(RedisProperties redisProperties) {

        //添加额外属性
        JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
                .clientName(redisProperties.getClientName())
                .usePooling().poolConfig(getGenericObjectJedisPoolConfig(redisProperties)).and().readTimeout(redisProperties.getTimeout())
                .build();

        //单实例连接配置
//        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisProperties.getHost());
//        configuration.setPort(redisProperties.getPort());
//        configuration.setPassword(redisProperties.getPassword());

        //集群连接配置
        RedisClusterConfiguration configuration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
        configuration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
        configuration.setPassword(RedisPassword.of(redisProperties.getPassword()));

        return new JedisConnectionFactory(configuration, clientConfig);
    }
}

2.springboot2.1.x-jedis

RedisConfig.java类

/**
 * @author zcx
 */
@Configuration
public class RedisConfig {

    /**
     * springboot2.1.x 使用 jedis 连接redis单实例或集群,需要添加以下的选项
     * 目的:为当前应用添加连接redis的标识,方便多应用连接同一个redis的问题查找
     */
    @Bean
    public RedisConnectionFactory connectionFactory(RedisProperties redisProperties) {

        //添加额外属性
        JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
                //客户端名称需要再这里写死
                .clientName("AppName")
                .usePooling().poolConfig(getGenericObjectJedisPoolConfig(redisProperties)).and().readTimeout(redisProperties.getTimeout())
                .build();

        //单实例连接配置
//        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisProperties.getHost());
//        configuration.setPort(redisProperties.getPort());
//        configuration.setPassword(redisProperties.getPassword());

        //集群连接配置
        RedisClusterConfiguration configuration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
        configuration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
        configuration.setPassword(RedisPassword.of(redisProperties.getPassword()));

        return new JedisConnectionFactory(configuration, clientConfig);
    }
}

 

本文地址:https://blog.csdn.net/weixin_39523456/article/details/109638676

相关标签: Redis