springboot集成redisserver;
package cn.cai.microservice.redisconfig;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
/**
*
*/
@Configuration
@EnableCaching
@SuppressWarnings({ “rawtypes”, “unchecked” })
public class RedisConfig extends CachingConfigurerSupport {
/**
* 生成key的策略
* @return
*/
@Override
@Bean
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();
};
}
/**
* 管理缓存
*/
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
return rcm;
}
/**
* RedisTemplate配置
*/
@Bean
public RedisTemplate<String, String> redisTemplate(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;
}
}
===================================================
package cn.cai.microservice.redisconfig;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
-
@author: daizhiqing
-
@Description: Redis缓存服务
-
@date: 2017/12/31
*/
@Service
@SuppressWarnings({“unchecked”,“rawtypes”})
public class RedisServer {@Autowired
private RedisTemplate redisTemplate;/**
- 写入缓存
- @param key
-
缓存key
- @param value
-
缓存value
- @return
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
//LogTrace.error(e.getMessage(), e);
}
return result;
}
/**
- 写入缓存设置失效时间
- @param key
-
缓存key
- @param value
-
缓存value
- @param expireTime
-
缓存失效时间
- @return
*/
public boolean set(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
LogTrace.error(e.getMessage(), e);
}
return result;
}
/**
- 设置已有缓存的缓存时间
- @param key
-
缓存key
- @param expireTime
-
缓存失效时间
- @return
*/
public boolean expire(final String key, Long expireTime) {
return redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
}
/**
- 批量删除缓存-keys
- @param keys
-
缓存key的List集合
*/
public void remove(final String… keys) {
for (String key : keys) {
remove(key);
}
}/**
- 批量删除缓存-给定模式
- @param pattern
-
给定模式 pattern
*/
public void removePattern(final String pattern) {
Set keys = redisTemplate.keys(pattern);
if (keys.size() > 0) {
redisTemplate.delete(keys);
}
}/**
- 删除缓存
- @param key
-
缓存key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}/**
- 判断一个缓存是否存在
- @param key
-
缓存key
- @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
- 读取缓存
- @param key
-
缓存key
- @return
*/
public String get(final String key) {
if (StringUtils.isEmpty(key)) {
return null;
}
Object result = null;
if (exists(key)) {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
}
return null == result ? null : result.toString();
}
/**
- 哈希添加缓存
- @param key
-
缓存key
- @param hashKey
-
Hash-key
- @param value
-
缓存value
*/
public void hashSet(String key, String hashKey, String value) {
HashOperations<String, String, String> hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}/**
- 哈希获取缓存
- @param key
-
缓存key
- @param hashKey
-
Hash-key
- @return
*/
public String hashGet(String key, String hashKey) {
HashOperations<String, String, String> hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
/**
- 删除一个hash 中的 key
- @param key
- @param hashKey
- @return
*/
public Long hashDel(String key, Object hashKey) {
HashOperations<String, String, String> hash = redisTemplate.opsForHash();
return hash.delete(key, hashKey);
}
/**
- 获取对应一个hash map
- @param key
- @return
*/
public Map<String, String> hashEntries(String key) {
HashOperations<String, String, String> hash = redisTemplate.opsForHash();
return hash.entries(key);
}
/**
- 无序set集合添加缓存
- @param key
-
缓存key
- @param value
-
缓存value
*/
public void sadd(String key, Object value) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key, value);
}/**
- 无序set集合获取缓存
- @param key
-
缓存key
- @return
*/
public Set smembers(String key) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
- 有序集合添加缓存
- @param key
-
缓存key
- @param value
-
缓存value
- @param scoure
*/
public void zAdd(String key, Object value, double scoure) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/**
- 有序集合获取缓存
- @param key
-
缓存key
- @param scoure
-
score最小值,闭区间
- @param scoure1
-
score最大值,闭区间
- @return
*/
public Set rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
/**
- 获取一个缓存剩余有效时间
- 1、不存在的 key // 指令:TTL key 返回(integer) -2
- 2、存在,但没有设置剩余生存时间 // 指令 TTL key 返回 (integer) -1
- 3、有剩余生存时间的 key // 指令 TTL key 返回秒(integer)
- @param key
-
缓存key
- @return
*/
public Long getExpire(String key) {
return redisTemplate.getExpire(key);
}
/**
- 获取一个缓存剩余有效时间
- 1、不存在的 key // 指令:TTL key 返回(integer) -2
- 2、存在,但没有设置剩余生存时间 // 指令 TTL key 返回 (integer) -1
- 3、有剩余生存时间的 key // 指令 TTL key 返回秒(integer)
- @param key
-
缓存key
- @return
*/
public Long getExpireByTime(String key) {
return redisTemplate.getExpire(key,TimeUnit.SECONDS);
}
/************************************************
- 有序list 集合操作
********************************************/
/ - 列表添加(leftPush依次由左边添加;返回添加成功后list size )
- @param key
-
缓存key
- @param val
-
缓存value
- @return
*/
public Long leftPush(String key, Object val , long time) {
ListOperations<String, Object> list = redisTemplate.opsForList();
Long size = list.leftPush(key, val );
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return size;
}
/**
- 列表添加(rightPush依次有右边添加;返回添加后 list size )
- @param key
-
缓存key
- @param val
-
缓存value
- @return
*/
public Long rightPush(String key, Object val, long time) {
ListOperations<String, Object> list = redisTemplate.opsForList();
Long size = list.rightPush(key, val);
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return size;
}
/**
- 删除最左边的那个项 (rightPush 添加 删除最早一条 ;leftPush 添加 删除最晚一条 )
- @param key
-
缓存key
- @return
*/
public Object leftPop(String key) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.leftPop(key);
}
/**
- 删除最右边的那个项 (rightPush 添加 删除最晚一条 ;leftPush 添加 删除最早一条 )
- @param key
-
缓存key
- @return
*/
public Object rightPop(String key) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.rightPop(key);
}
/**
- 列表获取(获得list集合 【 0 ,-1 代表所有值】)
- @param key
-
缓存key
- @return
*/
public List getList(String key) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(key, 0, -1);
}
/**
- 传入list 集合 key 和需要 删除的下标,返回移除数量
- @param key
-
缓存key
- @param index
-
需要删除的下标
- @return
*/
public Long remove(String key, int index) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.remove(key, 0, list.index(key, index));
}
public Long incrBy(String key, long value){
return redisTemplate.opsForValue().increment(key,value);
}
}
======================================
package cn.cai.microservice.redisconfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisCommands;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
/**
-
Created by Velsson on 2018/3/8 0008.
*/
@Component
public class RedisLock {private static final Logger logger = LoggerFactory.getLogger(RedisLock.class);
@Autowired
private RedisTemplate redisTemplate;private ThreadLocal lockFlag = new ThreadLocal<>();
private ThreadLocal sqlLine = new ThreadLocal<>();
//释放锁的原子操作lua脚本
public static final String UNLOCK_LUA;/**
- 默认的锁超时时间:15秒
/
private Long default_expire = 15000L;
/* - 默认的重试次数 100次
/
private Integer default_retryTimes = 100;
/* - 默认的重试间隔时间:0.3秒
*/
private Long default_sleepMillis = 300L;
static {
StringBuilder sb = new StringBuilder();
sb.append("if redis.call(“get”,KEYS[1]) == ARGV[1] ");
sb.append("then “);
sb.append(” return redis.call(“del”,KEYS[1]) ");
sb.append("else “);
sb.append(” return 0 ");
sb.append("end ");
UNLOCK_LUA = sb.toString();
}/**
- 是否开启sql记录
- @param key
- @param openSqlLine
- @return
*/
public boolean lock(String key, boolean openSqlLine) {
return lock(key, null, null, null, openSqlLine);
}
public boolean lock(String key) {
return lock(key, null, null, null, false);
}/**
- 获取redisKey
- @return
*/
public String getRedisKey() {
return lockFlag.get();
}
public AtomicInteger getSqlLine() {
return sqlLine.get();
}/**
- @param key 锁住的key
- @param expire 锁存在时间
- @param retryTimes 重试次数
- @param sleepMillis 重试间隔
- @return
*/
public boolean lock(String key, Long expire, Integer retryTimes, Long sleepMillis, boolean openSqlLine) {
expire = expire == null || expire < 0 ? default_expire : expire;
retryTimes = retryTimes == null || retryTimes <= 0 ? default_retryTimes : retryTimes;
sleepMillis = sleepMillis == null || sleepMillis <= 0 ? default_sleepMillis : sleepMillis;
boolean result = false;
do {
result = setRedis(key, expire);
if (!result) {
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException e) {
logger.error(“休眠线程异常”, e);
return false;
}
}
} while ((!result) && retryTimes-- > 0);
if (result && openSqlLine) sqlLine.set(new AtomicInteger(0));
return result;
}
private boolean setRedis(final String key, final long expire) {
try {
Object result = redisTemplate.execute(new RedisCallback() {
@Override
public String doInRedis(RedisConnection connection) throws DataAccessException {
JedisCommands commands = (JedisCommands) connection.getNativeConnection();
String uuid = UUID.randomUUID().toString();
lockFlag.set(uuid);
return commands.set(key, uuid, “NX”, “PX”, expire);
}
});
return !StringUtils.isEmpty(result);
} catch (Exception e) {
logger.error(“设置redis锁异常”, e);
}
return false;
}public boolean releaseLock(String key) {
try {
//为了防止内部嵌套的锁释放时删除了lockFlag的值导致外层锁释放时报错,所以采取删除key的方式来解决
String flag = lockFlag.get();
if (StringUtils.isEmpty(flag)){
redisTemplate.delete(key);
return true;
}final List<String> keys = new ArrayList<>(); keys.add(key); final List<String> args = new ArrayList<>(); args.add(flag); Long result = (Long) redisTemplate.execute(new RedisCallback<Long>() { public Long doInRedis(RedisConnection connection) throws DataAccessException { Object nativeConnection = connection.getNativeConnection(); if (nativeConnection instanceof JedisCluster) { return (Long) ((JedisCluster) nativeConnection).eval(UNLOCK_LUA, keys, args); } else if (nativeConnection instanceof Jedis) { return (Long) ((Jedis) nativeConnection).eval(UNLOCK_LUA, keys, args); } return 0L; } }); return result != null && result > 0; } catch (Exception e) { logger.error("释放redis锁异常", e); } finally { if (null != this.getSqlLine()) { sqlLine.remove(); } lockFlag.remove(); } return false;
}
}
=====& - 默认的锁超时时间:15秒