1.原理图
2.Leader/Follower模式
3.Timer和ScheduledThreadPoolExucutor区别
4.自行实现指定时间执行的定时任务
5.Quartz实现
参考文档:https://www.w3cschool.cn/quartz_doc/quartz_doc-2put2clm.html
/**
* 获得分布式锁
*
* @param redisClientId Redis客户端ID
* @return bool
*/
public boolean redisDistributedLock(String key, String redisClientId, long timeout, TimeUnit unit) {
ValueOperations<String, String> ops = redisTemplate.opsForValue();
if (ops.setIfAbsent(key, redisClientId, timeout, unit)) {
return true;
}
String cacheClientId = ops.get(key);
if (cacheClientId.equals(redisClientId)) {
redisExpire(key, timeout, unit);
return true;
}
return false;
}
/**
* 执行定时任务
*/
public void runBenchGameDelayTask(BenchDelayTaskType type) {
while (true) {
Set<ZSetOperations.TypedTuple<String>> typedTuples = benchGameCacheService.benchGameTaskZRange(type);
if (typedTuples.size() > 0) {
benchGameTaskProcess(type, typedTuples);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
log.error("[runBenchGameDelayTask] type={}, error={}", type.getData(), e);
}
}
}
在quartz的集群解决方案里有张表scheduler_locks,quartz采用了悲观锁的方式对triggers表进行行加锁,以保证任务同步的正确性。一旦某一个节点上面的线程获取了该锁,那么这个Job就会在这台机器上被执行,同时这个锁就会被这台机器占用。同时另外一台机器也会想要触发这个任务,但是锁已经被占用了,就只能等待,直到这个锁被释放
quartz的分布式调度策略是以数据库为边界资源的一种异步策略。各个调度器都遵守一个基于数据库锁的操作规则从而保证了操作的唯一性
原理图
缺点:quartz的分布式只是解决了高可用的问题,并没有解决任务分片的问题,还是会有单机处理的极限
TBSchedule是一款非常优秀的高性能分布式调度框架,广泛应用于阿里巴巴、淘宝、支付宝、京东、聚美、汽车之家、国美等很多互联网企业的流程调度系统。tbschedule在时间调度方面虽然没有quartz强大,但是它支持分片功能。和quartz不同的是,tbschedule使用ZooKeeper来实现任务调度的高可用和分片
原理图
TBSchedule的分布式机制是通过灵活的Sharding方式实现的,分片的规则由客户端决定,比如可以按所有数据的ID按10取模分片、按月份分片等等
BSchedule会定时扫描当前服务器的数量,重新进行任务分配。TBSchedule不仅提供了服务端的高性能调度服务,还提供了一个scheduleConsole的war包,随着宿主应用的部署直接部署到服务器,可以通过web的方式对调度的任务、策略进行监控管理,以及实时更新调整
Elastic-Job当当开源的分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务
原理图:
特点:
特性如下: