SpringBoot 項目接入 Redis 集群
Hello 大家好,我是鴨血粉絲,Redis 想必大家一定不會陌生,平常工作中或多或少都會用到,不管是用來存儲登錄信息還是用來緩存熱點數(shù)據(jù),對我們來說都是很有幫助的。但是 Redis 的集群估計并不是每個人都會用到,因為很多業(yè)務(wù)場景或者系統(tǒng)都是一些簡單的管理系統(tǒng),并不會需要用到 Redis 的集群環(huán)境。
阿粉之前也是這樣,項目中用的的 Redis 是個單機(jī)環(huán)境,但是最近隨著終端量的上升,慢慢的發(fā)現(xiàn)單機(jī)已經(jīng)快支撐不住的,所以思考再三決定將 Redis 的環(huán)境升級成集群。下面阿粉給大家介紹一下在升級的過程中項目中需要調(diào)整的地方,這篇文章不涉及集群的搭建和配置,感興趣的同學(xué)自行搜索。
配置參數(shù)
因為這篇文章不介紹 Redis 集群的搭建,這里我們假設(shè)已經(jīng)有了一個 Redis 的集群環(huán)境,我們項目中需要調(diào)整以下幾個部分
-
修改配置參數(shù),集群的節(jié)點和密碼配置; -
確保引入的 Jedis版本支持設(shè)置密碼,spring-data-redis1.8 以上,SpringBoot1.5 以上才支持設(shè)置密碼; -
注入 RedisTemplate; -
編寫工具類;
修改配置參數(shù)
############### Redis 集群配置 #########################
spring.custome.redis.cluster.nodes=172.20.0.1:7001,172.20.0.2:7002,172.20.0.3:7003
spring.custome.redis.cluster.max-redirects=3
spring.custome.redis.cluster.max-active=500
spring.custome.redis.cluster.max-wait=-1
spring.custome.redis.cluster.max-idle=500
spring.custome.redis.cluster.min-idle=20
spring.custome.redis.cluster.timeout=3000
spring.custome.redis.cluster.password=redis.cluster.password
引入依賴(如果需要)
確保 SpringBoot 的版本大于 1.4.x 如果不是的話,采用如下配置,先排除 SpringBoot 中舊版本 Jedis 和 spring-data-redis,再依賴高版本的 Jedis 和 spring-data-redis。
org.springframework.boot
spring-boot-starter-data-redis
redis.clients
jedis
org.springframework.data
spring-data-redis
redis.clients
jedis
2.9.0
org.springframework.data
spring-data-redis
1.8.0.RELEASE
注入 RedisTemplate
注入 RedisTemplate 我們需要三個組件,分別是JedisConnectionFactory 、RedisClusterConfiguration、JedisPoolConfig,下面是注入RedisTempalte 的代碼。先根據(jù)配置創(chuàng)建 JedisConnectFactory 同時需要配置 RedisClusterConfiguration、JedisPoolConfig,最后將JedisConnectionFactory 返回用于創(chuàng)建RedisTemplate
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
public class RedisClusterConfig {
@Bean(name = "redisTemplate")
@Primary
public RedisTemplate redisClusterTemplate(@Value("${spring.custome.redis.cluster.nodes}") String host,
@Value("${spring.custome.redis.cluster.password}") String password,
@Value("${spring.custome.redis.cluster.timeout}") long timeout,
@Value("${spring.custome.redis.cluster.max-redirects}") int maxRedirect,
@Value("${spring.custome.redis.cluster.max-active}") int maxActive,
@Value("${spring.custome.redis.cluster.max-wait}") int maxWait,
@Value("${spring.custome.redis.cluster.max-idle}") int maxIdle,
@Value("${spring.custome.redis.cluster.min-idle}") int minIdle) {
JedisConnectionFactory connectionFactory = jedisClusterConnectionFactory(host, password,
timeout, maxRedirect, maxActive, maxWait, maxIdle, minIdle);
return createRedisClusterTemplate(connectionFactory);
}
private JedisConnectionFactory jedisClusterConnectionFactory(String host, String password,
long timeout, int maxRedirect, int maxActive, int maxWait, int maxIdle, int minIdle) {
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
List
nodeList =
new ArrayList<>();
String[] cNodes = host.split(
",");
//分割出集群節(jié)點
for (String node : cNodes) {
String[] hp = node.split(
":");
nodeList.add(
new RedisNode(hp[
0], Integer.parseInt(hp[
1])));
}
redisClusterConfiguration.setClusterNodes(nodeList);
redisClusterConfiguration.setPassword(password);
redisClusterConfiguration.setMaxRedirects(maxRedirect);
// 連接池通用配置
GenericObjectPoolConfig genericObjectPoolConfig =
new GenericObjectPoolConfig();
genericObjectPoolConfig.setMaxIdle(maxIdle);
genericObjectPoolConfig.setMaxTotal(maxActive);
genericObjectPoolConfig.setMinIdle(minIdle);
genericObjectPoolConfig.setMaxWaitMillis(maxWait);
genericObjectPoolConfig.setTestWhileIdle(
true);
genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(
300000);
JedisClientConfiguration.DefaultJedisClientConfigurationBuilder builder = (JedisClientConfiguration.DefaultJedisClientConfigurationBuilder) JedisClientConfiguration
.builder();
builder.connectTimeout(Duration.ofSeconds(timeout));
builder.usePooling();
builder.poolConfig(genericObjectPoolConfig);
JedisConnectionFactory connectionFactory =
new JedisConnectionFactory(redisClusterConfiguration, builder.build());
// 連接池初始化
connectionFactory.afterPropertiesSet();
return connectionFactory;
}
private RedisTemplate createRedisClusterTemplate(JedisConnectionFactory redisConnectionFactory) {
RedisTemplate
redisTemplate =
new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer
