1. Redis整合Lettuce池配置多个实例

Redis 是目前业界使用最广泛的内存数据存储。相比 Memcached,Redis 支持更丰富的数据结构,例如 hashes, lists, sets ,sortedsets等。数据库有分库分表,当然redis也能实现mysql一样的分库逻辑。本文介绍 Redis 在 Spring Boot 中分库的应用场景。

2. 快速上手

1、引入依赖包

<!-- 引入 redis 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 引入 Lettuce池 依赖 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
<!-- 引入 fastjson 依赖,序列化使用的是fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.44</version> 
</dependency>

  

SpringBoot 提供了对 Redis 集成的组件包:spring-boot-starter-data-redis,spring-boot-starter-data-redis依赖于spring-data-redis 和 lettuce 。lettuce使用netty NIO来管理连接对象的,十分高效且线程安全,多个线程可共享一个connection对象。

SpringBoot2.0升级了redis池,从jedis升级到了lettuce,而且用户可无感知的切换到lettuce。

2.添加配置文件

两种添加配置文件的方式,一种是application.properties,另一种是application.yml。读者选择一种即可。

application.properties

#redis db1
spring.redis.redis-onedb.database=1
spring.redis.redis-onedb.hostName=localhost
spring.redis.redis-onedb.port=6379
spring.redis.redis-onedb.timeout=5000
#redis db2
spring.redis.redis-twodb.database=2
spring.redis.redis-twodb.hostName=localhost
spring.redis.redis-twodb.port=6379
spring.redis.redis-twodb.timeout=5000


spring.redis.lettuce.pool.MaxTotal=50
spring.redis.lettuce.pool.minIdle=1
spring.redis.lettuce.pool.maxWaitMillis=5000
spring.redis.lettuce.pool.maxIdle=5
spring.redis.lettuce.pool.testOnBorrow=true
spring.redis.lettuce.pool.testOnReturn=true
spring.redis.lettuce.pool.testWhileIdle=true

  

application.yml

spring:
  redis:
    lettuce:
      pool:
        MaxTotal: 50
        minIdle: 1
        maxWaitMillis: 5000
        maxIdle: 5
        testOnBorrow: true
        testOnReturn: true
        testWhileIdle: true
    redis-twodb:
      database: 1
      hostName: localhost
      port: 6379
      timeout: 5000
    redis-onedb:
      database: 2
      hostName: localhost
      port: 6379
      timeout: 5000

  

3.配置类RedisConfig

@Configuration
public class RedisConfig {
	
	
@Bean
@ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
@Scope(value = "prototype")
public GenericObjectPoolConfig redisPool(){
    return new GenericObjectPoolConfig();
}

@Bean
@ConfigurationProperties(prefix = "spring.redis.redis-onedb")
public RedisStandaloneConfiguration redisConfigA(){
    return new RedisStandaloneConfiguration();
}


@Primary
@Bean
public LettuceConnectionFactory factoryA(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfigA){
    LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder()
            .poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build();
    return new LettuceConnectionFactory(redisConfigA, clientConfiguration);
}


@Bean(name = "oneRedis")
public StringRedisTemplate redisBusTemplate(@Qualifier("factoryA") LettuceConnectionFactory factoryA){
    StringRedisTemplate template = getRedisTemplate();
    template.setConnectionFactory(factoryA);
    return template;
}



@Bean
@ConfigurationProperties(prefix = "spring.redis.redis-twodb")
public RedisStandaloneConfiguration redisConfigB(){
    return new RedisStandaloneConfiguration();
}

@Bean
public LettuceConnectionFactory factoryB(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfigB){
    LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder()
            .poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build();
    return new LettuceConnectionFactory(redisConfigB, clientConfiguration);
}


@Bean(name = "twoRedis")
public StringRedisTemplate redisLoginTemplate(@Qualifier("factoryB")LettuceConnectionFactory factoryB){
    StringRedisTemplate template = getRedisTemplate();
    template.setConnectionFactory(factoryB);
    return template;
}

private StringRedisTemplate getRedisTemplate(){
    StringRedisTemplate template = new StringRedisTemplate();
    template.setValueSerializer(new GenericFastJsonRedisSerializer());
    template.setValueSerializer(new StringRedisSerializer());
    return template;
}
}

  

RedisConfig类中配置的Lettuce多例模式池对象。

@Bean
@ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
@Scope(value = "prototype")
public GenericObjectPoolConfig redisPool(){
    return new GenericObjectPoolConfig();
}

  

我们来梳理一下:

  1. RedisTemplate对象 依赖 LettuceConnectionFactory对象;

  2. LettuceConnectionFactory对象 依赖 RedisStandaloneConfiguration池配置对象以及Redis配置对象。

  3. oneRedis->factoryA->redisConfigA + redisPool , twoRedis->factoryB->redisConfigB + redisPool

3. 测试效果

编写测试代码RedisTestor类的run方法。

System.out.println("在db1中设置key的值为:hello db1");
oneRedis.opsForValue().set("key", "hello db1");
System.out.println("在db2中设置key的值为:hello db1");
twoRedis.opsForValue().set("key", "hello db1");

System.out.println("db1中key:"+oneRedis.opsForValue().get("key"));
System.out.println("db2中key:"+twoRedis.opsForValue().get("key"));

  

查看db1、db2的数据

alt

完整的demo项目,请关注公众号“前沿科技bot“并发送"状态机"获取。

查看更多 “Java架构师方案” 系列文章 以及 SpringBoot2.0学习示例

alt