最近公司产品需求,需要使用同一个redis数据库服务使用不同的序列化方式的redisTemplate对缓存数据库进行读写操作,
目前大部分网上的文章在实作Redis分流时,都是以Jedis为样例,但SpringBoot在2.x版本之后已经将Redis库替换成Lettuce了
之前我写过一篇文章就是 SpringBoot2.x Redis多数据源配置(Vavr函数式编程方式实现)
这篇文章是我使用Vavr函数式编程方式实现
进行实现的,接下来我将使用一种更简单的方式进行操作
当然在进行实现案例之前我们还是要基于springboot基础的redis库包还是要引入进来的
项目pom配置
使用Spring Boot集成Redis,只需要将spring-boot-starter-data-redis
和commons-pool2
加到依赖即可
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
配置文件
spring.redis
开头的都是Spring Boot自动注入需要加载的配置
spring:
redis:
database: 0
host: localhost
port: 6379
password:
timeout: 60000
lettuce:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制) 默认 8
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
max-idle: 8 # 连接池中的最大空闲连接 默认 8
min-idle: 0 # 连接池中的最小空闲连接 默认 0
redis-db-2:
database: 2
host: 127.0.0.1
port: 6379
password:
timeout: 60000
lettuce:
pool:
max-active: 8
max-wait: 8
max-idle: 8
min-idle: 0
RedisConfigure
package com.xiaozhangge.redis.configure;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.vavr.Tuple;
import io.vavr.Tuple6;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
* Created by xiaozhangge on 2020-01-10.
*
* @Value("${spring.redis-db-2.database}") int database,
* @Value("${spring.redis-db-2.host}") String host,
* @Value("${spring.redis-db-2.port}") int port,
* @Value("${spring.redis-db-2.password}") String password,
* @Value("${spring.redis-db-2.timeout}") long timeout,
* @Value("${spring.redis-db-2.lettuce.pool.max-active}") int maxActive,
* @Value("${spring.redis-db-2.lettuce.pool.max-wait}") int maxWait,
* @Value("${spring.redis-db-2.lettuce.pool.max-idle}") int maxIdle,
* @Value("${spring.redis-db-2.lettuce.pool.min-idle}") int minIdle
*/
@EnableCaching
@Configuration
public class RedisConfigure {
/**
* string redis Template创建操作
*
* @param database Redis数据库索引
* @param timeout 连接超时时间(秒)
* @param maxActive 连接池最大连接数(使用负值表示沒有限制)
* @param maxWait 连接池最大等待时间(使用负值表示沒有限制)
* @param maxIdle 连接池中的最大空闲连接
* @param minIdle 连接池中的最小空闲连接
* @param host Redis服务地址
* @param password Redis服务密码
* @param port Redis服务器连接端口
*/
@Bean(name = "stringRedisTemplate")
public StringRedisTemplate stringRedisTemplate(
@Value("${spring.redis-db-2.database}")
int database,
@Value("${spring.redis-db-2.timeout:5}")
long timeout,
@Value("${spring.redis-db-2.lettuce.pool.max-active}")
int maxActive,
@Value("${spring.redis-db-2.lettuce.pool.max-wait}")
int maxWait,
@Value("${spring.redis-db-2.lettuce.pool.max-idle}")
int maxIdle,
@Value("${spring.redis-db-2.lettuce.pool.min-idle}")
int minIdle,
@Value("${spring.redis-db-2.host}")
String host,
@Value("${spring.redis-db-2.password}")
String password,
@Value("${spring.redis-db-2.port}")
int port
) {
// connection config
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
configuration.setHostName(host);
configuration.setPort(port);
configuration.setPassword(RedisPassword.of(password));
configuration.setDatabase(database);
// pool config
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
genericObjectPoolConfig.setMaxTotal(maxActive);
genericObjectPoolConfig.setMinIdle(minIdle);
genericObjectPoolConfig.setMaxIdle(maxIdle);
genericObjectPoolConfig.setMaxWaitMillis(maxWait);
// create connection factory
LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder();
builder.poolConfig(genericObjectPoolConfig);
builder.commandTimeout(Duration.ofSeconds(timeout));
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(
configuration, builder.build()
);
connectionFactory.afterPropertiesSet();
// create redis template
return createStringRedisTemplate(connectionFactory);
}
/**
* 建立StringRedisTemplate
* 此function不能加 @Bean 否则onnectionFactory 将会一律采用预设值
*/
private StringRedisTemplate createStringRedisTemplate(
RedisConnectionFactory redisConnectionFactory
) {
StringRedisTemplate redisTemplate = new StringRedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
具体默认的配置大家可以参考开篇讲解的上一篇文章,我这里仅仅介绍了自定义额外的连接信息。
首先是第一个连接配置信息,这个名称是first,代表第一组Redis连接池配置信息,功能名称会影响到后续在使用上的操作,如果想要另外取名的话可以将bean加上名称@Bean(name=”您的名字””)
在这个函数中接收到框架原型建立的RedisConnectionFactory为参数,将该该工厂传到最底下的createRedisTemplate()来建立StringRedisTemplate,所以如果希望建立的是其他RedisTemplate连接模板的话就可以修改createRedisTemplate()
Redis连接池,如此一来要我们开发过程中操作时忘了标注要使用Redis的话,便会采用这默认的连接池,
接着来看第二个功能,在这个功能中可以看到设定档中第二条连接池的参数,前面提到我们只需要修改连接池的地址信息,所以关于pool等相关设定还是抓第一条连接池的,这边就看大家有没有需要自行修改〜
设置完毕第二条连接池的设置后,进行的事情实际上就是自己建立连接工厂,先设置好Config相关对象,然后创建LettuceConnectionFactory对象,最后和第一个功能相同,将工厂引入createRedisTemplate()来生成RedisTemplate连接池
所以实际上我们要做的事情就是,设置定义的连接池就自定义的factory建立RedisTemplate物件来操作,额外的连线就进入设定档后,自己添加factory来生成RedisTemplate连接模板,就是这么简单〜
连接池建立好后就是实际的操作啦,操作方式也很简单,就用@Autowired就好,只是要带名称让Spring Boot知道你要使用的是其中RedisTemplate哪个连接池即可
@Autowired
@Qualifier("first")
StringRedisTemplate firstRedisTemplate;
@Autowired
@Qualifier("stringRedisTemplate")
StringRedisTemplate secondRedisTemplate;
示例代码:https://github.com/xiaomozhang/personal-life-example/tree/master/example-redis