背景:我们测试环境有两套,所以涉及俩套Redis存储,测试环境存储订单被锁的情况,解锁的话需要手动在对应的Redis DB中删除订单号key。为节省人工,考虑才测试平台做一个简单的功能,查询订单是否被锁,解锁(即删除订单号)
pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.properties
#redis数据源1 默认 第一套环境
# Redis 数据库索引(默认为 0)
spring.redis.database=0
# Redis 服务器地址
spring.redis.host=***.***.**.**
# Redis 服务器连接端口
spring.redis.port=5***
# Redis 服务器连接密码(默认为空)
spring.redis.password=0e17ba8627cd8f91
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=0
#redis数据源2 第二套环境
# Redis 数据库索引(默认为 0)
spring.redis2.database=0
# Redis 服务器地址
spring.redis2.host=**.**.**.**
spring.redis2.port=5***
# Redis 服务器连接密码(默认为空)
spring.redis2.password=283f90d469434509
自定
义config实现数据源的加载
package com.jrqa.riskpushvariabletestserver.configredis;
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.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheManager;
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.JedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
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.RedisSerializer;
/**
* by zfy
* 2019/5/6
*/
@Configuration
@EnableCaching
public class RedisConfigMain extends CachingConfigurerSupport {
/**
* 配置lettuce连接池
*
* @return
*/
@Bean
@ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
public GenericObjectPoolConfig redisPool() {
return new GenericObjectPoolConfig<>();
}
/**
* 配置第一个数据源的
*
* @return
*/
@Bean
// @ConfigurationProperties(prefix = "spring.redis")
public RedisStandaloneConfiguration redisConfig(@Value("${spring.redis.host}") String host, @Value("${spring.redis.port}") int port
, @Value("${spring.redis.database}") int db, @Value("${spring.redis.password}") String password) {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(host, port);
redisStandaloneConfiguration.setDatabase(db);
redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
return redisStandaloneConfiguration;
}
/**
* 配置第二个数据源
*
* @return
*/
@Bean
@ConfigurationProperties(prefix = "spring.redis2")
public RedisStandaloneConfiguration redisConfig2() {
return new RedisStandaloneConfiguration();
}
/**
* 配置第一个数据源的连接工厂
* 这里注意:需要添加@Primary 指定bean的名称,目的是为了创建两个不同名称的LettuceConnectionFactory
*
* @param config
* @param redisConfig
* @return
*/
@Bean("factory")
@Primary
public LettuceConnectionFactory factory(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfig) {
LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(config).build();
return new LettuceConnectionFactory(redisConfig, clientConfiguration);
}
@Bean("factory2")
public LettuceConnectionFactory factory2(GenericObjectPoolConfig config, RedisStandaloneConfiguration redisConfig2) {
LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(config).build();
return new LettuceConnectionFactory(redisConfig2, clientConfiguration);
}
/**
* 配置第一个数据源的RedisTemplate
* 注意:这里指定使用名称=factory 的 RedisConnectionFactory
* 并且标识第一个数据源是默认数据源 @Primary
*
* @param factory
* @return
*/
@Bean("redisTemplate")
@Primary
public RedisTemplate<String, String> redisTemplate(@Qualifier("factory") RedisConnectionFactory factory) {
return getStringStringRedisTemplate(factory);
}
/**
* 配置第一个数据源的RedisTemplate
* 注意:这里指定使用名称=factory2 的 RedisConnectionFactory
*
* @param factory2
* @return
*/
@Bean("redisTemplate2")
public RedisTemplate<String, String> redisTemplate2(@Qualifier("factory2") RedisConnectionFactory factory2) {
return getStringStringRedisTemplate(factory2);
}
/**
* 设置序列化方式 (这一步不是必须的)
*
* @param factory
* @return
*/
private RedisTemplate<String, String> getStringStringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
config数据加载代码参看
RedisStandaloneConfiguration的源码,因为刚开始我只用的注解
// @ConfigurationProperties(prefix = "spring.redis")
但是仅使用这行注解端口是取对了的,但是host取得默认值localhost,说明这用使用是不对的。参看源码后,使用以上实现方式ok。
使用
package com.jrqa.riskpushvariabletestserver.service.impl;
import com.jrqa.riskpushvariabletestserver.service.RiskOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* by zfy
* 2019/5/5
*/
@Service
public class RiskOrderServiceImpl implements RiskOrderService {
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate firstRedisTemplate;
@Autowired
@Qualifier("redisTemplate2")
private RedisTemplate secondRedisTemplate;
public boolean exists(String key) {
return firstRedisTemplate.hasKey(key);
}
public boolean remove(final String key) {
if (exists(key)) {
return firstRedisTemplate.delete(key);
}else {
return false;
}
}
@Override
public boolean exists(String key, String num) {
if ("1".equals(num)){
return firstRedisTemplate.hasKey(key);
}else if ("2".equals(num)){
return secondRedisTemplate.hasKey(key);
}
return false;
}
@Override
public boolean remove(String key, String num) {
boolean exists = exists(key, num);
if("1".equals(num) && exists){
return firstRedisTemplate.delete(key);
}else if ("2".equals(num) && exists){
return secondRedisTemplate.delete(key);
}
return false;
}
}