redis(7)-java集成三
使用Lettuce框架:
创建maven工程,引入依赖:
<dependency>
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>4.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.20.RELEASE</version>
</dependency>
redis.properties文件配置信息如下:
redis.sentinel.master=哨兵模式主
redis.sentinel.nodes=节点
redis.password=密码
redis.maxTotal=16
redis.maxIdle=8
redis.minIdle=8
redis.blockWhenExhausted=true
redis.maxWait=10000
redis.testOnBorrow=true
redis.testOnReturn=true
redis.testWhileIdle=true
redis.timeBetweenEvictionRunsMillis=30000
redis.minEvictableIdleTimeMillis=10000
哨兵模式配置类
@Component
public class RedisProperties {
@Value("${redis.password}")
private String password;
@Value("${redis.maxTotal}")
private int maxTotal;
@Value("${redis.maxIdle}")
private int maxIdle;
@Value("${redis.minIdle}")
private int minIdle;
@Value("${redis.blockWhenExhausted}")
private boolean isBlockWhenExhausted;
@Value("${redis.maxWait}")
private int maxWait;
@Value("${redis.testOnBorrow}")
private boolean isTestOnBorrow;
@Value("${redis.testOnReturn}")
private boolean isTestOnReturn;
@Value("${redis.testWhileIdle}")
private boolean isTestWhileIdle;
@Value("${redis.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;
@Value("${redis.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;
@Value("${redis.sentinel.master}")
private String master;
@Value("${redis.sentinel.nodes}")
private String nodes;
private Set<String> hosts;
@PostConstruct//@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
public void hosts() {
hosts = new HashSet<>();
hosts.addAll(Arrays.asList(nodes.split(",")));
}
public String getMaster() {
return master;
}
public void setMaster(String master) {
this.master = master;
}
public String getNodes() {
return nodes;
}
public void setNodes(String nodes) {
this.nodes = nodes;
}
public Set<String> getHosts() {
return hosts;
}
public void setHosts(Set<String> hosts) {
this.hosts = hosts;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getMaxTotal() {
return maxTotal;
}
public void setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
}
public int getMaxIdle() {
return maxIdle;
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public boolean isBlockWhenExhausted() {
return isBlockWhenExhausted;
}
public void setBlockWhenExhausted(boolean isBlockWhenExhausted) {
this.isBlockWhenExhausted = isBlockWhenExhausted;
}
public int getMaxWait() {
return maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public boolean isTestOnBorrow() {
return isTestOnBorrow;
}
public void setTestOnBorrow(boolean isTestOnBorrow) {
this.isTestOnBorrow = isTestOnBorrow;
}
public boolean isTestOnReturn() {
return isTestOnReturn;
}
public void setTestOnReturn(boolean isTestOnReturn) {
this.isTestOnReturn = isTestOnReturn;
}
public boolean isTestWhileIdle() {
return isTestWhileIdle;
}
public void setTestWhileIdle(boolean isTestWhileIdle) {
this.isTestWhileIdle = isTestWhileIdle;
}
public int getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public int getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
}
@Configuration
@EnableCaching
public class RedisClientConfiguration extends CachingConfigurerSupport {
@Resource
private RedisProperties redisProperties;
/**
* 配置连接池参数
*
* @return GenericObjectPool
*/
@Bean
public GenericObjectPoolConfig getRedisConfig() {
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
genericObjectPoolConfig.setMaxIdle(redisProperties.getMaxIdle());
genericObjectPoolConfig.setMaxTotal(redisProperties.getMaxTotal());
genericObjectPoolConfig.setMinIdle(redisProperties.getMinIdle());
// 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
genericObjectPoolConfig.setBlockWhenExhausted(redisProperties.isBlockWhenExhausted());
genericObjectPoolConfig.setMaxWaitMillis(redisProperties.getMaxWait());
// 在borrow一个实例时,是否提前进行alidate操作;如果为true,则得到的实例均是可用的
genericObjectPoolConfig.setTestOnBorrow(redisProperties.isTestOnBorrow());
// 调用returnObject方法时,是否进行有效检查
genericObjectPoolConfig.setTestOnReturn(redisProperties.isTestOnReturn());
// 在空闲时检查有效性, 默认false
genericObjectPoolConfig.setTestWhileIdle(redisProperties.isTestWhileIdle());
// 表示idle object evitor两次扫描之间要sleep的毫秒数;
genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(redisProperties.getTimeBetweenEvictionRunsMillis());
// 表示一个对象至少停留在idle状态的最短时间,
// 然后才能被idle object
// evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义;
genericObjectPoolConfig.setMinEvictableIdleTimeMillis(redisProperties.getMinEvictableIdleTimeMillis());
return genericObjectPoolConfig;
}
/**
*
* @Title: getDefaultLettucePool
* @Description:配置连接池
* @param sentinelConfiguration
* @param poolConfig
* @return DefaultLettucePool
* @throws
*/
@Bean
public DefaultLettucePool getDefaultLettucePool(RedisSentinelConfiguration sentinelConfiguration,
GenericObjectPoolConfig poolConfig) {
DefaultLettucePool defaultLettucePool = new DefaultLettucePool(sentinelConfiguration);
defaultLettucePool.setPoolConfig(poolConfig);
defaultLettucePool.setPassword(redisProperties.getPassword());
defaultLettucePool.afterPropertiesSet();
return defaultLettucePool;
}
@Bean
public StringRedisTemplate stringRedisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(lettuceConnectionFactory);
// todo 定制化配置
return stringRedisTemplate;
}
/**
*
* @Title: getLettuceConnectionFactory
* @Description: lettuce 连接工厂配置
* @param pool
* @return LettuceConnectionFactory
* @throws
*/
@Bean
public LettuceConnectionFactory lettuceConnectionFactory(LettucePool pool) {
LettuceConnectionFactory factory = new LettuceConnectionFactory(pool);
// 校验连接是否有效
factory.setValidateConnection(true);
factory.setTimeout(redisProperties.getMaxWait());
factory.afterPropertiesSet();
return factory;
}
/**
*
* @Title: redisSentinelConfiguration
* @Description: 配置哨兵集群信息 master和host:ip
* @param sentinelProperties
* @return RedisSentinelConfiguration
* @throws
*/
@Bean
public RedisSentinelConfiguration redisSentinelConfiguration(RedisProperties sentinelProperties) {
return new RedisSentinelConfiguration(sentinelProperties.getMaster(), sentinelProperties.getHosts());
}
@Bean
@Override
public KeyGenerator keyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
};
}
/**
*
* @Title: getRedisCacheManager
* @Description: 缓存管理器 使用redisTemplate操作
* @param redisTemplate
* @return RedisCacheManager
* @throws
*/
@Bean
public RedisCacheManager getRedisCacheManager(RedisTemplate<String, Object> redisTemplate) {
return new RedisCacheManager(redisTemplate);
}
/**
*
* @Title: redisTemplate
* @Description: RedisTemplate配置 在单独使用redisTemplate的时候 重新定义序列化方式
* @param lettuceConnectionFactory
* @return RedisTemplate<String,Object>
* @throws
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
// 设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
// key序列化
redisTemplate.setKeySerializer(stringSerializer);
// value序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// Hash key序列化
redisTemplate.setHashKeySerializer(stringSerializer);
// Hash value序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
// redisTemplate.setEnableTransactionSupport(true);
return redisTemplate;
}
}
public interface IRedisTemplate {
/**
* String字符串命令 redis结构为<key,value>
*
* @param key
* @param value
* @return
*/
public boolean set(String key, Object value);
/**
*
* 描述:批量设置值.
*
* @param map
* void
*/
void mutiSet(Map<String, ?> map);
/**
*
* @Title: get @Description: 获取redis的数据 @param key @return Object
* 返回类型 @throws
*/
Object get(String key);
/**
* 获取原来key键对应的值并重新赋新值。
*
* @param key
* @return String
*/
public boolean getAndSet(String key, Object value);
/**
* 判断缓存中是否有对应的value
*
* @param key
* @return String
*/
public boolean exists(String key);
/**
* 删除对应的value
*
* @param key
* @return String
*/
public boolean remove(String key);
/**
* 删除对应的value
*
* @param key
* @return String
*/
public void removes(Collection<String> keys);
}
@Slf4j
@Service
@DependsOn("redisTemplate")
public class SentinelRedisTemplate implements IRedisTemplate {
/**
* redisUtil.setIfAbsent 新加的带有超时的setIfAbsent 脚本
*/
String newSetIfAbsentScriptStr = " if 1 == redis.call('setnx',KEYS[1],ARGV[1]) then"
+ " redis.call('expire',KEYS[1],ARGV[2])" + " return 1;" + " else" + " return 0;" + " end;";
public RedisScript<Boolean> newSetIfAbsentScript = new DefaultRedisScript<>(newSetIfAbsentScriptStr, Boolean.class);
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* String字符串命令 redis结构为<key,value>
*
* @param key
* @param value
* @return
*/
public boolean set(String key, Object value) {
boolean result = false;
try {
if (StringUtils.isEmpty(key) || value == null) {
return result;
}
redisTemplate.opsForValue().set(key, value);
result = true;
} catch (Exception e) {
log.error("SentinelRedisTemplate set int error,key:{}", key, e);
}
return result;
}
/**
*
* 描述:批量设置值.
*
* @param map
* void
*/
public void mutiSet(Map<String, ?> map) {
try {
redisTemplate.opsForValue().multiSet(map);
} catch (Exception e) {
log.error("SentinelRedisTemplate mutiSet error,keySet:{}", map.keySet(), e);
}
}
/**
* 根据key获取redis的值
*
*/
@Override
public Object get(String key) {
if (StringUtils.isEmpty(key)) {
return null;
}
if (exists(key)) {
return redisTemplate.opsForValue().get(key);
}
return null;
}
@Override
public boolean getAndSet(String key, Object value) {
boolean result = false;
if (StringUtils.isEmpty(key)) {
return false;
}
try {
if (exists(key)) {
redisTemplate.opsForValue().getAndSet(key, value);
} else {
redisTemplate.opsForValue().set(key, value);
}
result = true;
} catch (Exception e) {
log.error("SentinelRedisTemplate getAndSet int error,key:{}", key, e);
}
return result;
}
/**
* 判断缓存中是否有对应的value
*
* @param key
* @return
*/
@Override
public boolean exists(String key) {
if (StringUtils.isNotEmpty(key)) {
return redisTemplate.hasKey(key);
}
return false;
}
/**
* 删除对应的value
*
* @param key
*/
@Override
public boolean remove(String key) {
boolean result = false;
try {
if (exists(key)) {
redisTemplate.delete(key);
}
result = true;
} catch (Exception e) {
log.error("SentinelRedisTemplate remove int error,key:{}", key, e);
}
return result;
}
/**
* 批量删除对应的value
*
* @param keys
*/
@Override
public void removes(Collection<String> keys) {
try {
if (CollectionUtils.isNotEmpty(keys)) {
redisTemplate.delete(keys);
}
} catch (Exception e) {
log.error("SentinelRedisTemplate remove int error", e);
}
}
public boolean setIfAbsent(String key, String value, Long seconds) {
List<String> keys = new ArrayList<>();
keys.add(key);
Object[] args = { value, seconds };
return redisTemplate.<Boolean> execute(newSetIfAbsentScript, keys, args);
}
/**
*
* 描述:查询过期时间.
*
* @param key
* @return Long
*/
public Long getExpire(String key) {
return redisTemplate.getExpire(key);
}
}
浙公网安备 33010602011771号