redisson分布式ロックの接面プログラミング
11777 ワード
application.properties :
spring.redislocal.host: redis://127.0.0.1
spring.redislocal.port: 6379
spring.redislocal.password: 111111
spring.redislocal.sleeptime: 10000
redisツールクラスの作成:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.util.SortedMap;
import java.util.TreeMap;
public class RedisUtils {
private static Logger logger= LoggerFactory.getLogger(RedisUtils.class);
private static RedisUtils redisUtils;
private static RedissonClient redissonClient;
private RedisUtils(){}
/**
*
* @return
*/
public static RedisUtils getInstance(){
if(redisUtils==null)
synchronized (RedisUtils.class) {
if(redisUtils==null) redisUtils=new RedisUtils();
}
return redisUtils;
}
/**
* config Redisson
* Redisson Redis Server
* @param config
* @return
*/
public static RedissonClient getRedisson(Config config){
RedissonClient redisson= Redisson.create(config);
logger.info(" Redis Server");
return redisson;
}
/**
* ip Redisson
* @param ip
* @param port
* @return
*/
public static RedissonClient getRedisson(String ip,String port){
Config config=new Config();
config.useSingleServer().setAddress(ip+":"+port);
RedissonClient redisson=Redisson.create(config);
logger.info(" Redis Server"+"\t"+" "+ip+":"+port+" ");
return redisson;
}
/**
* Redisson
* @param redisson
*/
public static void closeRedisson(RedissonClient redisson){
redisson.shutdown();
logger.info(" Redis Client ");
}
/**
*
* @param redisson
* @param objectName
* @return
*/
public static RBucket getRBucket(RedissonClient redisson, String objectName){
RBucket bucket=redisson.getBucket(objectName);
return bucket;
}
/**
* Map
* @param redisson
* @param objectName
* @return
*/
public static RMap getRMap(RedissonClient redisson, String objectName){
RMap map=redisson.getMap(objectName);
return map;
}
/**
*
* @param redisson
* @param objectName
* @return
*/
public static RSortedSet getRSortedSet(RedissonClient redisson, String objectName){
RSortedSet sortedSet=redisson.getSortedSet(objectName);
return sortedSet;
}
/**
*
* @param redisson
* @param objectName
* @return
*/
public static RSet getRSet(RedissonClient redisson, String objectName){
RSet rSet=redisson.getSet(objectName);
return rSet;
}
/**
*
* @param redisson
* @param objectName
* @return
*/
public static RList getRList(RedissonClient redisson,String objectName){
RList rList=redisson.getList(objectName);
return rList;
}
/**
*
* @param redisson
* @param objectName
* @return
*/
public RQueue getRQueue(RedissonClient redisson,String objectName){
RQueue rQueue=redisson.getQueue(objectName);
return rQueue;
}
/**
*
* @param redisson
* @param objectName
* @return
*/
public static RDeque getRDeque(RedissonClient redisson,String objectName){
RDeque rDeque=redisson.getDeque(objectName);
return rDeque;
}
/**
* Redisson 1.2
* 1.2.2
* @param redisson
* @param objectName
* @return
*/
public static RBlockingQueue getRBlockingQueue(RedissonClient redisson,String objectName){
RBlockingQueue rb=redisson.getBlockingQueue(objectName);
return rb;
}
/**
*
* @param redisson
* @param objectName
* @return
*/
public static RLock getRLock(RedissonClient redisson,String objectName){
RLock rLock=redisson.getLock(objectName);
return rLock;
}
/**
*
* @param redisson
* @param objectName
* @return
*/
public static RAtomicLong getRAtomicLong(RedissonClient redisson,String objectName){
RAtomicLong rAtomicLong=redisson.getAtomicLong(objectName);
return rAtomicLong;
}
/**
*
* @param redisson
* @param objectName
* @return
*/
public static RCountDownLatch getRCountDownLatch(RedissonClient redisson,String objectName){
RCountDownLatch rCountDownLatch=redisson.getCountDownLatch(objectName);
return rCountDownLatch;
}
/**
* Topic
* @param redisson
* @param objectName
* @return
*/
public static RTopic getRTopic(RedissonClient redisson,String objectName){
RTopic rTopic=redisson.getTopic(objectName);
return rTopic;
}
/**
* key
* redis key "DistRedisLock+" + lockKey + @DistRedisLockKey
*
* @param point
* @param lockKey
* @return
*/
public static String getLockKey(ProceedingJoinPoint point, String lockKey) {
try {
lockKey = "DistRedisLock:" + lockKey;
Object[] args = point.getArgs();
if (args != null && args.length > 0) {
MethodSignature methodSignature = (MethodSignature)point.getSignature();
Annotation[][] parameterAnnotations = methodSignature.getMethod().getParameterAnnotations();
SortedMap keys = new TreeMap<>();
for (int i = 0; i < parameterAnnotations.length; i ++) {
RedisLockKey redisLockKey = getAnnotation(RedisLockKey.class, parameterAnnotations[i]);
if (redisLockKey != null) {
Object arg = args[i];
if (arg != null) {
keys.put(redisLockKey.order(), arg.toString());
}
}
}
if (keys != null && keys.size() > 0){
for (String key : keys.values()) {
lockKey += key;
}
}
}
return lockKey;
} catch (Exception e) {
logger.error("getLockKey error.", e);
}
return null;
}
/**
*
* @param annotationClass
* @param annotations
* @param
* @return
*/
private static T getAnnotation(final Class annotationClass, final Annotation[] annotations) {
if (annotations != null && annotations.length > 0) {
for (final Annotation annotation : annotations) {
if (annotationClass.equals(annotation.annotationType())) {
return (T) annotation;
}
}
}
return null;
}
public static RedissonClient createClient(String address , String pass) {
if(redissonClient == null) {
synchronized (RedisUtils.class) {
if(redissonClient == null) {
Config config = new Config();
SingleServerConfig singleSerververConfig = config.useSingleServer();
singleSerververConfig.setAddress(address);
singleSerververConfig.setPassword(pass);
redissonClient = RedisUtils.getInstance().getRedisson(config);
}
}
}
return redissonClient;
}
}
書き込み注記RedisLock:
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RedisLock {
/**
* key
* , @P4jSynKey ,
* redis key "DistRedisLock+" + lockKey + @RedisLockKey
*/
String lockKey();
/**
*
* , 5
*/
long keepMills() default 5 * 1000;
/**
* ,
* @return
*/
long maxSleepMills() default 20 * 1000;
}
書き込み注記RedisLockKey:
import java.lang.annotation.*;
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RedisLockKey {
/**
* key
*/
int order() default 0;
}
書き込みスライス:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
@Component
@Aspect
public class RedisLockAspect {
private static Logger logger= LoggerFactory.getLogger(RedisLockAspect.class);
@Value("${spring.redislocal.host}:${spring.redislocal.port}")
String address;
@Value("${spring.redislocal.password}")
String password;
@Value("${spring.redislocal.sleeptime}")
int sleepTime ;
@Around("execution(* com.juphoon.coachtalk.appserver.service..*(..))&& @annotation(RedisLock)")
public Object lock(ProceedingJoinPoint point) throws Throwable {
RLock lock = null;
Boolean status = false;
Object object = null;
logger.info("into Aspect!");
try {
RedisLock redisLock = getDistRedisLockInfo(point);
RedisUtils redisUtils = RedisUtils.getInstance();
RedissonClient redissonClient = RedisUtils.createClient(address, password);
String lockKey = redisUtils.getLockKey(point, redisLock.lockKey());
lock = redisUtils.getRLock(redissonClient, lockKey);
if (lock != null) {
status = lock.tryLock(redisLock.maxSleepMills(), redisLock.keepMills(), TimeUnit.MILLISECONDS);
if (status) {
object = point.proceed();
}
}
} finally {
if (lock != null && status) {
lock.unlock();
}
}
return object;
}
private RedisLock getDistRedisLockInfo(ProceedingJoinPoint point) {
try {
MethodSignature methodSignature = (MethodSignature) point.getSignature();
Method method = methodSignature.getMethod();
return method.getAnnotation(RedisLock.class);
} catch (Exception e) {
logger.info(e.getMessage());
}
return null;
}
}
実装の呼び出し:
@RedisLock(lockKey = "lockKey", keepMills = 15000)
public void updateXXX(@RedisLockKey(order = 1) Long userId, @RedisLockKey(order = 0) Long advisorId) {
}