一、配置文件
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.yml
spring:
application:
name: double-redis-lettuce
profiles:
active: dev
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
server:
port: 8008
sys:
redis:
one:
host: 192.168.1.2
port: 5009
timeout: 6000
lettuce:
pool:
max-active: 30
max-idle: 10
max-wait: 6000
slave:
host: 192.168.1.3
port: 5010
database: 1
two:
timeout: 12000
lettuce:
pool:
max-active: 30
max-idle: 10
max-wait: 6000
sentinel:
master: redis_sentinel_master
nodes:
- sentinel-group001.mk.com:10003
- sentinel-group002.mk.com:10003
- sentinel-group003.mk.com:10003
二、配置Configuration Bean
Lettuce配置基类
public class AbstractLettuceRedisConfig {
public LettuceConnectionFactory createLettuceConnectionFactory(ClientResources clientResources, RedisProperties properties) {
LettuceClientConfiguration clientConfiguration = getLettuceClientConfiguration(clientResources, properties);
RedisSentinelConfiguration sentinelConf = getSentinelConfig(properties);
if (sentinelConf != null) {
return new LettuceConnectionFactory(sentinelConf, clientConfiguration);
}
RedisClusterConfiguration clusterConf = getClusterConfiguration(properties);
if (clusterConf != null) {
return new LettuceConnectionFactory(clusterConf, clientConfiguration);
}
return new LettuceConnectionFactory(getStandaloneConfig(properties), clientConfiguration);
}
private RedisStandaloneConfiguration getStandaloneConfig(RedisProperties properties) {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
if (StringUtils.hasText(properties.getUrl())) {
ConnectionInfo connectionInfo = parseUrl(properties.getUrl());
config.setHostName(connectionInfo.getHostName());
config.setPort(connectionInfo.getPort());
config.setPassword(RedisPassword.of(connectionInfo.getPassword()));
} else {
config.setHostName(properties.getHost());
config.setPort(properties.getPort());
config.setPassword(RedisPassword.of(properties.getPassword()));
}
config.setDatabase(properties.getDatabase());
return config;
}
private RedisClusterConfiguration getClusterConfiguration(RedisProperties properties) {
if (properties.getCluster() == null) {
return null;
}
RedisProperties.Cluster clusterProperties = properties.getCluster();
RedisClusterConfiguration config = new RedisClusterConfiguration(clusterProperties.getNodes());
if (clusterProperties.getMaxRedirects() != null) {
config.setMaxRedirects(clusterProperties.getMaxRedirects());
}
if (properties.getPassword() != null) {
config.setPassword(RedisPassword.of(properties.getPassword()));
}
return config;
}
private RedisSentinelConfiguration getSentinelConfig(RedisProperties properties) {
RedisProperties.Sentinel sentinelProperties = properties.getSentinel();
if (sentinelProperties != null) {
RedisSentinelConfiguration config = new RedisSentinelConfiguration();
config.master(sentinelProperties.getMaster());
config.setSentinels(createSentinels(sentinelProperties));
if (properties.getPassword() != null) {
config.setPassword(RedisPassword.of(properties.getPassword()));
}
config.setDatabase(properties.getDatabase());
return config;
}
return null;
}
private List<RedisNode> createSentinels(RedisProperties.Sentinel sentinel) {
List<RedisNode> nodes = new ArrayList<>();
for (String node : sentinel.getNodes()) {
try {
String[] parts = StringUtils.split(node, ":");
Assert.state(parts.length == 2, "Must be defined as 'host:port'");
nodes.add(new RedisNode(parts[0], Integer.valueOf(parts[1])));
} catch (RuntimeException ex) {
throw new IllegalStateException("Invalid redis sentinel " + "property '" + node + "'", ex);
}
}
return nodes;
}
private LettuceClientConfiguration getLettuceClientConfiguration(ClientResources clientResources, RedisProperties properties) {
LettuceClientConfiguration.LettuceClientConfigurationBuilder builder = createBuilder(Optional.ofNullable(properties.getLettuce())
.map(v -> v.getPool()).orElse(null));
applyProperties(builder, properties);
if (StringUtils.hasText(properties.getUrl())) {
customizeConfigurationFromUrl(builder, properties);
}
builder.clientResources(clientResources);
return builder.build();
}
private LettuceClientConfiguration.LettuceClientConfigurationBuilder createBuilder(RedisProperties.Pool pool) {
if (pool == null) {
return LettuceClientConfiguration.builder();
}
return new PoolBuilderFactory().createBuilder(pool);
}
private LettuceClientConfiguration.LettuceClientConfigurationBuilder applyProperties(
LettuceClientConfiguration.LettuceClientConfigurationBuilder builder, RedisProperties properties) {
if (properties.isSsl()) {
builder.useSsl();
}
if (properties.getTimeout() != null) {
builder.commandTimeout(properties.getTimeout());
}
if (properties.getLettuce() != null) {
RedisProperties.Lettuce lettuce = properties.getLettuce();
if (lettuce.getShutdownTimeout() != null && !lettuce.getShutdownTimeout().isZero()) {
builder.shutdownTimeout(properties.getLettuce().getShutdownTimeout());
}
}
return builder;
}
private void customizeConfigurationFromUrl(LettuceClientConfiguration.LettuceClientConfigurationBuilder builder, RedisProperties properties) {
ConnectionInfo connectionInfo = parseUrl(properties.getUrl());
if (connectionInfo.isUseSsl()) {
builder.useSsl();
}
}
private ConnectionInfo parseUrl(String url) {
try {
URI uri = new URI(url);
boolean useSsl = (url.startsWith("rediss://"));
String password = null;
if (uri.getUserInfo() != null) {
password = uri.getUserInfo();
int index = password.indexOf(':');
if (index >= 0) {
password = password.substring(index + 1);
}
}
return new ConnectionInfo(uri, useSsl, password);
} catch (URISyntaxException ex) {
throw new IllegalArgumentException("Malformed url '" + url + "'", ex);
}
}
private static class ConnectionInfo {
private final URI uri;
private final boolean useSsl;
private final String password;
public ConnectionInfo(URI uri, boolean useSsl, String password) {
this.uri = uri;
this.useSsl = useSsl;
this.password = password;
}
public boolean isUseSsl() {
return this.useSsl;
}
public String getHostName() {
return this.uri.getHost();
}
public int getPort() {
return this.uri.getPort();
}
public String getPassword() {
return this.password;
}
}
private static class PoolBuilderFactory {
public LettuceClientConfiguration.LettuceClientConfigurationBuilder createBuilder(RedisProperties.Pool properties) {
return LettucePoolingClientConfiguration.builder().poolConfig(getPoolConfig(properties));
}
private GenericObjectPoolConfig<?> getPoolConfig(RedisProperties.Pool properties) {
GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();
config.setMaxTotal(properties.getMaxActive());
config.setMaxIdle(properties.getMaxIdle());
config.setMinIdle(properties.getMinIdle());
if (properties.getTimeBetweenEvictionRuns() != null) {
config.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRuns().toMillis());
}
if (properties.getMaxWait() != null) {
config.setMaxWaitMillis(properties.getMaxWait().toMillis());
}
return config;
}
}
}
(1)第一个Redis配置
public class OneLettuceRedisConfig extends AbstractLettuceRedisConfig{
@Bean
public StringRedisTemplate oneStringRedisTemplate(@Autowired @Qualifier("oneRedisConnectionFactory")
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
public LettuceConnectionFactory oneRedisConnectionFactory(@Autowired @Qualifier("oneRedisProperties") RedisProperties properties,
ClientResources clientResources) throws UnknownHostException {
return createLettuceConnectionFactory(clientResources, properties);
}
@Bean
@ConfigurationProperties("sys.redis.one")
public RedisProperties oneRedisProperties() {
return new RedisProperties();
}
}
(2)第二个Redis配置(主)
public class TwoLettuceRedisConfig extends AbstractLettuceRedisConfig{
@Primary
@Bean
public StringRedisTemplate twoStringRedisTemplate(@Autowired @Qualifier("twoRedisConnectionFactory")
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Primary
@Bean
public LettuceConnectionFactory twoRedisConnectionFactory(@Autowired @Qualifier("twoRedisProperties") RedisProperties properties,
ClientResources clientResources) throws UnknownHostException {
return createLettuceConnectionFactory(clientResources, properties);
}
@Primary
@Bean
@ConfigurationProperties("sys.redis.two")
public RedisProperties twoRedisProperties() {
return new RedisProperties();
}
}
(3)redis导入配置
@Configuration
@Import({OneLettuceRedisConfig.class, TwoLettuceRedisConfig.class})
public class RedisConfig {
}