700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > spring boot基于redis的分布式定时任务

spring boot基于redis的分布式定时任务

时间:2022-02-09 11:39:31

相关推荐

spring boot基于redis的分布式定时任务

第一步. 自动配置类

主启动类添加:@EnableScheduling //开启定时任务

aop和redis POM添加:

<!--redis驱动--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--aop面向切面编程--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>

自定义分布式定时任务注解

/*** @program:* @description: 定时任务锁* @author: wangZhiDong* @created: /11/29 09:06*/@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface TaskLock {/*** 定时任务名称* @return*/String name() default "";/*** redis缓存key值* @return*/String key();/*** 过期时间单位s (自动解锁时间,防止死锁)* @return*/int expired();/*** 执行完毕是否解锁* @return*/boolean unLock() default true;}

定义分布式定时任务 切面具体实现

/*** @program:* @description: 定时任务锁切面* @author: wangZhiDong* @created: /10/29 09:12*/@Aspect@Component@Slf4j@AllArgsConstructor@Order(10)public class TaskLockAspect {private RedisTemplate redisTemplate;@Pointcut("@annotation(com.wang.timedtask.annotation.TaskLock)")public void TaskLockAspect() {}@Around("TaskLockAspect() && @annotation(taskLock)")public Object doAround(ProceedingJoinPoint proceedingJoinPoint,TaskLock taskLock) throws Throwable {String value = UUID.randomUUID().toString();try {if (lock(taskLock.key(), value, taskLock.expired())) {return proceedingJoinPoint.proceed();}} catch (Exception e) {log.error("定时任务执行失败,{}", taskLock.key(), e);} finally {// 执行完毕解除锁if (!taskLock.unLock()) {return null;}String lockValue = getLockValue(taskLock.key());if (StringUtils.isEmpty(lockValue) || !lockValue.equals(value)) {return null;}// 解锁设置为延时1SunLock(taskLock.key());}return null;}/*** 加锁* @param key* @param value* @param time* @return*/public boolean lock(String key , String value , int time){return redisTemplate.opsForValue().setIfAbsent(key , value , time , TimeUnit.SECONDS);}/*** 解锁* @param key*/public void unLock(String key){redisTemplate.expire(key , 1 , TimeUnit.SECONDS);}/*** 获取锁值* @param key* @return*/public String getLockValue(String key){return (String) redisTemplate.opsForValue().get(key);}}

简单使用

/*** @Author wangZhiDong* @Date /8/22* 启动数据纠正**/@Slf4j@Componentpublic class TransferService {public static int num = 0;DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");@Scheduled(cron = "0/5 * * * * ?")@TaskLock(name = "测试分布式定时任务5秒执行一次", key = "test_task",expired = 5)public void start(){num++;System.out.println(LocalDateTime.now().format(formatter)+"第"+num+"次执行的是第一个");}/*** 使用 public 的 定时任务才行*/@Scheduled(cron = "0/5 * * * * ?")@TaskLock(name = "测试分布式定时任务5秒执行一次", key = "test_task",expired = 5)public void start2(){TransferService.num++;System.out.println(LocalDateTime.now().format(formatter)+"第"+TransferService.num+"次执行的是第二个");}@Scheduled(cron = "0/5 * * * * ?")@TaskLock(name = "测试分布式定时任务5秒执行一次", key = "test_task",expired = 5)public void start3(){TransferService.num++;System.out.println(LocalDateTime.now().format(formatter)+"第"+TransferService.num+"次执行的是第三个");}}

执行结果:

-12-01 14:35:40第1次执行的是第一个

-12-01 14:35:45第2次执行的是第二个

-12-01 14:35:50第3次执行的是第三个

-12-01 14:35:55第4次执行的是第三个

-12-01 14:36:00第5次执行的是第二个

-12-01 14:36:05第6次执行的是第一个

-12-01 14:36:10第7次执行的是第三个

-12-01 14:36:15第8次执行的是第一个

-12-01 14:36:20第9次执行的是第二个

-12-01 14:36:25第10次执行的是第三个

-12-01 14:36:30第11次执行的是第一个

...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。