database: 0
dnsMonitoringInterval: 5000 #DNS监测时间间隔(毫秒),默认5000
threads: 16
nettyThreads: 32
codec: !<org.redisson.codec.JsonJacksonCodec> {}
#“transportMode”: “NIO”
集群模式:
clusterServersConfig:
idleConnectionTimeout: 10000
pingTimeout: 1000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
reconnectionTimeout: 3000
failedAttempts: 3
password: null
subscriptionsPerConnection: 5
clientName: null
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
slaveSubscriptionConnectionMinimumIdleSize: 1
slaveSubscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 32
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 32
masterConnectionPoolSize: 64
readMode: “SLAVE”
nodeAddresses:
“redis://127.0.0.1:7004”
“redis://127.0.0.1:7001”
“redis://127.0.0.1:7000”
scanInterval: 1000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {}
#“transportMode”:“NIO”
注入配置文件
这里读取配置文件根据环境读取的
RedissionConfig
package com.dzhjj.dzhjjapi.config;
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.redisson.config.Config;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
/**
@Auther: heng
@Date: 2020/12/3 13:56
@Description: redission分布式锁
@Version 1.0.0
*/
@Order(2)
@Slf4j
@Configuration
public class RedissionConfig {
//@Autowired
// private RedisProperties redisProperties;
@Autowired
private Environment env;
/**
单机模式
@return
//
@Bean
public RedissonClient redissonClient() {
RedissonClient redissonClient;
Config config = new Config();
String url = “redis://” + redisProperties.getHost() + “:” + redisProperties.getPort();
SingleServerConfig serverConfig = config.useSingleServer()
.setAddress(url)
.setTimeout(3000)
.setDatabase(redisProperties.getDatabase())
.setConnectionPoolSize(64)
.setConnectionMinimumIdleSize(50);
if (StringUtils.isNotBlank(redisProperties.getPassword())) {
serverConfig.setPassword(redisProperties.getPassword());
}
try {
redissonClient = Redisson.create(config);
return redissonClient;
} catch (Exception e) {
log.error(“RedissonClient init redis url:[{}], Exception:”, url, e);
return null;
}
}*/
@Bean(destroyMethod = “shutdown”)
public RedissonClient redisson() throws IOException {
Config config = Config.fromYAML(new ClassPathResource(“application-single-”+env.getActiveProfiles()[0]+".yml").getInputStream());
RedissonClient redisson = Redisson.create(config);
return redisson;
}
}
测试分布式锁代码
@Autowired
private RedissonClient redissonClient;
public Object testRedisLoak(){
Boolean result=false;
final String lockKey= “RedissonLock”;
RLock lock=redissonClient.getLock(lockKey);
try {
//TODO:第一个参数30s=表示尝试获取分布式锁,并且最大的等待获取锁的时间为30s
//TODO:第二个参数10s=表示上锁之后,10s内操作完毕将自动释放锁
Boolean cacheRes=lock.tryLock(10,10, TimeUnit.SECONDS);
return cacheRes;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//TODO:释放锁
lock.unlock();
}
return result;
}
开始集成注解模式
定义注解: RsionLock
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
/**
Description:
分布式锁的注解在同一个注解中成对使用即可,比如示例代码中,value和path就是互为别名。
但是要注意一点,@AliasFor标签有一些使用限制,但是这应该能想到的,比如要求互为别名的属性属性值类型,默认值,都是相同的,互为别名的注解必须成对出现,比如value属性添加了@AliasFor(“path”),
那么path属性就必须添加@AliasFor(“value”),另外还有一点,互为别名的属性必须定义默认值。
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RsionLock {
/**
支持spring El表达式
锁的资源,key。
*/
//@AliasFor(“value”)
String key() default “”;
/**
支持spring El表达式
锁的资源,value。
如果不为空这回拼接key
*/
//@AliasFor(“key”)
String value() default “”;
/**
持锁时间,单位:秒
TODO:10s=表示上锁之后,10s内操作完毕将自动释放锁
*/
long lockTime() default 10;
/**
- 当获取失败时候动作
*/
// LockFailAction action() default LockFailAction.CONTINUE;
/*public enum LockFailAction{
//* 放弃 //
GIVEUP,
//* 继续 //
CONTINUE;
}*/
/**
等待时间,单位:秒
TODO:10s=表示尝试获取分布式锁,并且最大的等待获取锁的时间为10s
@return
*/
int waitTime() default 10;
/**
是否自动延期机制
默认不自动延期
@return
*/
boolean isWatchDog() default false;
/**
延期时间 单位:秒
@return
*/
int watchDogTime() default 2;
}
定义该注解切面 LockAspectConfiguration
import com.dzhjj.dzhjjapi.annotations.RsionLock;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
/**
@Auther: heng
@Date: 2020/12/3 17:50
@Description: LockAspectConfiguration
@Version 1.0.0
*/
@Slf4j
@Aspect
@Configuration
public class LockAspectConfiguration {
private ExpressionParser parser = new SpelExpressionParser();
private LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
@Autowired
private RedissonClient redissonClient;
/**
- 定义切入点
*/
@Pointcut("@annotation(com.dzhjj.dzhjjapi.annotations.RsionLock)")
private void lockPoint() {
}
/**
环绕通知
@param pjp pjp
@return 方法返回结果
@throws Throwable throwable
*/
@Around(“lockPoint()”)
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
RsionLock lockAction = method.getAnnotation(RsionLock.class);
String logKey = getLogKey(lockAction, pjp, method);