前言一、不使用自动生效的定时任务二、使用redis 创建一个标识来判断(此处引用同事的想法)三、使用XXLJOB四、使用ShedLock + redis最后说明
前言
场景:现在集群越来越普及,一个服务拥有多个实例时,何如避免定时任务重复执行?
一、不使用自动生效的定时任务
详见:https://blog.csdn.net/qq_37700773/article/details/109385361?spm=1001.2014.3001.5501
但是不建议使用,原因是不方便。
。
二、使用redis 创建一个标识来判断(此处引用同事的想法)定时任务启动的时候,先去redis查询是指定key是否存在值(这里使用reids 的AtomicLong)
这里使用的是redission,实质上执行的这句代码:
// CacheUtil.incrAtomicLong(Key)这句代码的底层
public long incrAtomicLong(String key) {
return redissonClient.getAtomicLong(key).incrementAndGet();
}
三、使用XXLJOB
xxljob是一个单独的服务,思路是:
1:业务系统内没有定时任务,而是将定时任务逻辑写成一个接口
2:在xxljob服务端管理台配置好参数,由xxljob服务定时调用业务系统
3:xxljob服务调用业务集群(xxljob请求网关/ng,最终请求哪个业务实例,由网关/ng规则决定)
xxljob这种模式,还是有点麻烦。而且我经常会忘记:还有xxljob?部署在哪?地址多少?
四、使用ShedLock + redis
推荐使用这个。对性能要求不是特别高的(性能要求在比肩某东、某宝的…这款肯定也不合适)
这个只是日常开发使用,董事任务的服务实例在十几个以内的,应该没啥问题。
推荐的主要原因是:很简单
spring项目中引入依赖:
net.javacrumbs.shedlock
shedlock-spring
4.0.4
net.javacrumbs.shedlock
shedlock-provider-redis-spring
2.5.0
增加shedLock的配置,使用的redis
package com.tao.scheduled.shedLock;
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.redis.spring.RedisLockProvider;
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
@EnableSchedulerLock(defaultLockAtMostFor = "PT30M")
public class ShedLockConfig {
@Bean
public LockProvider lockProvider(RedisTemplate redisTemplate) {
return new RedisLockProvider(redisTemplate.getConnectionFactory());
}
}
最简单的定时任务代码
package com.tao.scheduled.shedLock;
import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class ShedLockDemo {
// @Scheduled(cron = "0/2 * * * * ?") 每2秒执行一次
@Scheduled(cron = "0/2 * * * * ?")
@SchedulerLock(name = "scheduleDemo01")
public void ScheduleDemo01() {
log.info("开启定时任务......");
}
}
启动类加上注:@EnableScheduling
//@EnableFeignClients//开启feign
@EnableSwagger2 //开启 Swagger
@SpringBootApplication
@EnableScheduling//开启定时任务
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class);
System.out.println("======......项目启动成功......======"+ServerPortConfig.host+":"+ ServerPortConfig.serverPort);
}
}
测试方法:
idea启动两个实例,直接观察日志…
这篇文章,记录的是工作中遇到的问题,写的比较水。主要用于工作总结和记录



