redis分布式锁解决集群服务器定时任务重复执行问题
2019-08-03 15:57
1211 查看
问题描述
将带有定时任务的项目部署在单台测试环境上,完全没问题。生产上是两台集群服务器,项目部署上去发现定时任务的模块同时在两台机器上各执行了一遍,这将会导致其他意外的发生。
解决方案----redis分布式锁
使用redis分布式锁,为定时任务唯一指定的key加锁,并设置锁超时时间。当触发定时任务时,一台服务的任务进入切面,通过setNX(key,value)方法为唯一的key加锁,如果当前key不存在,将放入缓存,并返回true,通过expire(key,second)设置锁超时时间,结束后跳出执行定时任务方法。第二台服务任务进入时,设置锁的时候发现该锁已存在于缓存,并返回false,不跳转到执行定时任务方法。
核心代码
1.分布式锁切面
@Aspect @Slf4j @Component public class CacheLockAspect { private static final String LOCK_VALUE = "locked"; @Autowired private RedisConnection connection; @Around("execution(* *.*(..)) && @annotation(com.common.annotation.CacheLock)") public void cacheLockPoint(ProceedingJoinPoint pjp) { Method cacheMethod = null; for (Method method : pjp.getTarget().getClass().getMethods()) { if (null!=method.getAnnotation(CacheLock.class)){ cacheMethod = method; break; } } try { String lockKey = cacheMethod.getAnnotation(CacheLock.class).lockedPrefix(); long timeOut = cacheMethod.getAnnotation(CacheLock.class).expireTime(); if(null == lockKey){ throw new ManagerException(ErrorMsgEnum.LOCK_NAME_EMPTY); } if (connection.setNX(lockKey.getBytes(),LOCK_VALUE.getBytes())) { connection.expire(lockKey.getBytes(),timeOut); log.info("method:{}获取锁:{},开始运行!",cacheMethod,lockKey); pjp.proceed(); return; } log.info("method:{}未获取锁:{},运行失败!",cacheMethod,lockKey); } catch (Throwable e) { log.error("method:{},运行错误!",cacheMethod,e); throw new ManagerException(ErrorMsgEnum.LOCK_JOB_ERROR,e); } } }
2.手写方法级注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CacheLock { String lockedPrefix() default ""; //redis 锁key的前缀 long expireTime() default 10; //key在redis里存在的时间,1000S }
3.定时任务服务
@Slf4j @Service public class TimeTaskService { /** * 执行定时任务 **/ @Scheduled(cron = "0 0 1 * * ?") @CacheLock(lockedPrefix = "TimeTaskService",expireTime=30) public void executeTask() { System.out.println("hello world!"); } }
相关文章推荐
- 解决 集群 环境 定时任务 重复执行 的问题
- 使用redis分布式锁解决spring schedule集群部署重复执行问题
- 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法
- 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法
- 预发环境与生产环境共享数据库时定时任务重复执行问题解决
- 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法
- 完美解决多应用服务器负载均衡环境下spring quartz同一定时任务重复执行问题
- 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法
- 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法
- 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法
- 完美解决多应用服务器负载均衡环境下spring quartz同一定时任务重复执行问题
- 解决Spring定时计划任务重复执行两次或多次(实例被构造两次)问题的方法
- 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法
- 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法
- Linux下shell脚本在crontab中一个周期执行不完,下周期任务被重复执行的问题解决
- Elastic-Job任务重复执行问题解决
- 解决spring定时任务执行两次和tomcat部署缓慢的问题
- 解决spring quartz定时任务执行2次的问题
- 定时任务会重复执行俩次的解决方法
- 多节点服务器定时任务重复处理的问题