探寻用户自定义定时任务的实践方案(7)
2023-05-03 来源:飞速影视
releaseLock() //记录异常日志,更新任务状态和失败原因 if (record != null) { } } if (!scheduleTask.getLocalScheduleDefine().getOnce()&&executed) { Date next = scheduleTask.cronGenerator().next(executeDate); long delay = next.getTime() - executeDate.getTime(); SpringTaskExecutor.getExecutorService().schedule(() -> localWork.runJob(scheduleTask), delay, TimeUnit.MILLISECONDS); } }
如果要保证任务在集群中保证唯一执行可通过分布式锁实现,具体的key已给参考,因为没有提供集群节点注册的功能,负载均衡的调度只能依赖集群中节点获取锁的随机性,即那个节点获取到锁,任务在哪个节点执行。
当任务执行出错时(保存完执行记录后),不影响下一次任务的执行,但会更新此次任务执行的结果和失败原因。
任务设计小结
应用启动时,初始化任务,开启任务加载线程,开启任务调度线程。任务加载线程周期性的从 DB 中获取全部任务,并更新缓存中任务实例;调度线程负责对任务定义实例进行一系列的判断,决定是否交给执行线程池去执行,任务加载和调用可以使用一个定时线程池。
private ScheduledExecutorService internalScheduledExecutor = new ScheduledThreadPoolExecutor(2, new ThreadFactoryBuilder().setNameFormat("task-internal-%d").build());
执行任务的线程池接收到提交的任务,执行前后做统一处理,任务执行的具体业务逻辑交给具体的实现类去做。整个处理流程中,需要两张表(任务定义表 任务执行记录表),2 个定时线程池可完成。
总结
本文基于用户自定义定时任务的特点,从任务创建、任务加载、任务调度、任务执行四个方面详细的介绍了任务执行的过程,对定时任务中常见的问题和处理过程附带了部分代码供参考,在支持一般定时任务的同时给大家提供了一种用户自定义定时任务的实践方法。
本站仅为学习交流之用,所有视频和图片均来自互联网收集而来,版权归原创者所有,本网站只提供web页面服务,并不提供资源存储,也不参与录制、上传
若本站收录的节目无意侵犯了贵司版权,请发邮件(我们会在3个工作日内删除侵权内容,谢谢。)
www.fs94.org-飞速影视 粤ICP备74369512号