微服务配置Redis多数据源

这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

背景

在微服务概念中,不同的服务需要使用不同的数据库,包括mysqlredis,但是如果是需要高并发又与这样设计造成冲突,因为直接查询redis会更快一些。

集成Redis多数据源与lettuce连接池

springboot中集成redis多个数据源需要屏蔽starter中带有的原生RedisAutoConfiguration
并模拟RedisAutoConfiguration,设置多个redisTemplate的bean。并在使用时通过Autowired+Qualifier注入。

依赖添加

1
2
3
4
xml复制代码<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置文件

yaml文件中配置多数据源连接信息,配置一个端口为6379的默认Redis1和一个端口为6380的Redis2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
yml复制代码redis:
lettuce1:
host: localhost
password:
port: 6379
timeout: 5000
pool:
maxWaitMillis: 10000
minIdle: 5
maxIdle: 160
maxTotal: 500
lettuce2:
host: localhost
password:
port: 6380
timeout: 5000
pool:
maxWaitMillis: 10000
minIdle: 5
maxIdle: 160
maxTotal: 500

排除RedisAutoConfiguration

不使用默认的springboot进行加载初始化,必须要在注解中排除RedisAutoConfiguration

1
2
3
4
5
6
7
8
java复制代码@Import(value = {
RedisLettuceConfig1.class,
RedisLettuceConfig2.class
})

@SpringBootApplication(exclude = {
RedisAutoConfiguration.class
})

Redis1配置类

配置lettuce连接池、数据源、数据源的连接工厂、RedisTemplate。并设置序列化方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
java复制代码@EnableConfigurationProperties({RedisLettuceProperties1.class})
public class RedisLettuceConfig1 {
private static final String REDIS_STANDALONE_CONFIGURATION = "redisStandaloneConfiguration1";
private static final String LETTUCE_CLIENT_CONFIGURATION = "lettuceClientConfiguration1";
public static final String REDIS_CONNECTION_FACTORY = "redisLettuceConnectionFactory1";
public static final String REDIS_TEMPLATE = "redisLettuceTemplate1";

@Autowired
private RedisLettuceProperties1 redisProperties;

public RedisLettuceConfig1() {
}

@Bean(
name = {"redisStandaloneConfiguration1"}
)
public RedisStandaloneConfiguration redisStandaloneConfiguration() {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(this.redisProperties.getHost(), this.redisProperties.getPort());
if (!StringUtils.isEmpty(this.redisProperties.getPassword())) {
RedisPassword password = RedisPassword.of(this.redisProperties.getPassword());
configuration.setPassword(password);
}

configuration.setDatabase(this.redisProperties.getDbIndex());
return configuration;
}

@Bean(
name = {"lettuceClientConfiguration1"}
)
public LettuceClientConfiguration lettuceClientConfiguration() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMinIdle(this.redisProperties.getPool().getMinIdle());
config.setMaxIdle(this.redisProperties.getPool().getMaxIdle());
config.setMaxTotal(this.redisProperties.getPool().getMaxTotal());
config.setMaxWaitMillis((long)this.redisProperties.getPool().getMaxWaitMillis());
config.setTestOnBorrow(this.redisProperties.getPool().getTestOnBorrow());
config.setTestOnReturn(this.redisProperties.getPool().getTestOnReturn());
LettucePoolingClientConfiguration configuration = LettucePoolingClientConfiguration.builder().poolConfig(config).commandTimeout(Duration.ofMillis((long)this.redisProperties.getTimeout())).build();
return configuration;
}

@Bean(
name = {"redisLettuceConnectionFactory1"}
)
public RedisConnectionFactory redisConnectionFactory(@Qualifier("redisStandaloneConfiguration1") RedisStandaloneConfiguration redisStandaloneConfiguration, @Qualifier("lettuceClientConfiguration1") LettuceClientConfiguration lettuceClientConfiguration) {
LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, lettuceClientConfiguration);
return factory;
}

@Bean(
name = {"redisLettuceTemplate1"}
)
public RedisTemplate<String, Object> redisTemplate(@Qualifier("redisLettuceConnectionFactory1") RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate();
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
RedisSerializer<Object> objectSerializer = new JdkSerializationRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setValueSerializer(objectSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
redisTemplate.setHashValueSerializer(objectSerializer);
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}

}

Redis2配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
java复制代码@EnableConfigurationProperties({RedisLettuceProperties2.class})
public class RedisLettuceConfig2 {
private static final String REDIS_STANDALONE_CONFIGURATION = "redisStandaloneConfiguration2";
private static final String LETTUCE_CLIENT_CONFIGURATION = "lettuceClientConfiguration2";
public static final String REDIS_CONNECTION_FACTORY = "redisLettuceConnectionFactory2";
public static final String REDIS_TEMPLATE = "redisLettuceTemplate2";
@Autowired
private RedisLettuceProperties2 RedisLettuceProperties;

public RedisLettuceConfig2() {
}

@Bean(
name = {"redisStandaloneConfiguration2"}
)
public RedisStandaloneConfiguration redisStandaloneConfiguration() {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(this.RedisLettuceProperties.getHost(), this.RedisLettuceProperties.getPort());
if (!StringUtils.isEmpty(this.RedisLettuceProperties.getPassword())) {
RedisPassword password = RedisPassword.of(this.RedisLettuceProperties.getPassword());
configuration.setPassword(password);
}

configuration.setDatabase(this.RedisLettuceProperties.getDbIndex());
return configuration;
}

@Bean(
name = {"lettuceClientConfiguration2"}
)
public LettuceClientConfiguration lettuceClientConfiguration() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMinIdle(this.RedisLettuceProperties.getPool().getMinIdle());
config.setMaxIdle(this.RedisLettuceProperties.getPool().getMaxIdle());
config.setMaxTotal(this.RedisLettuceProperties.getPool().getMaxTotal());
config.setMaxWaitMillis((long)this.RedisLettuceProperties.getPool().getMaxWaitMillis());
config.setTestOnBorrow(this.RedisLettuceProperties.getPool().getTestOnBorrow());
config.setTestOnReturn(this.RedisLettuceProperties.getPool().getTestOnReturn());
LettucePoolingClientConfiguration configuration = LettucePoolingClientConfiguration.builder().poolConfig(config).commandTimeout(Duration.ofMillis((long)this.RedisLettuceProperties.getTimeout())).build();
return configuration;
}

@Bean(
name = {"redisLettuceConnectionFactory2"}
)
public RedisConnectionFactory redisConnectionFactory(@Qualifier("redisStandaloneConfiguration2") RedisStandaloneConfiguration redisStandaloneConfiguration, @Qualifier("lettuceClientConfiguration2") LettuceClientConfiguration lettuceClientConfiguration) {
LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, lettuceClientConfiguration);
return factory;
}


@Bean(
name = {"redisLettuceTemplate2"}
)
public RedisTemplate<String, Object> redisTemplate(@Qualifier("redisLettuceConnectionFactory2") RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate();
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
RedisSerializer<Object> objectSerializer = new JdkSerializationRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setValueSerializer(objectSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
redisTemplate.setHashValueSerializer(objectSerializer);
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}

}

测试

引用redisTemplate并指定来自哪个bean

1
2
3
4
5
6
java复制代码    @Autowired
@Qualifier(RedisLettuceConfig1.REDIS_TEMPLATE)
private RedisTemplate redisTemplate;

HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
String value = hashOperations.get("users", userId);

小结

springboot配置redis多数据源的过程比较简单,引入依赖包,添加配置,初始化Bean。
需要注意的是Redis有默认的实现类了,所以在装配使用的时候,要加上@Qualifier注解并指定前面Bean注入的名字,不然自动注入后会使用默认的配置,不能使用指定的Redis数据源。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%