V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Jverson
V2EX  ›  Java

用 springboot 和 quartz 撸了一个动态管理定时任务系统

  •  
  •   Jverson · 2017-12-22 22:00:54 +08:00 · 10425 次点击
    这是一个创建于 2530 天前的主题,其中的信息可能已经有所发展或是发生改变。

    对部门之前用 xml 配置搞得 quartz 定时任务系统忍无可忍,每次加个任务改个配置都得重新上线,这几天有空重构了一下,感觉清爽多了,看看大家有什么建议

    地址: https://github.com/jiwenxing/springboot-quartz

    总感觉集成 mq 有点重,好像 redis 也能实现同样的功能

    另外不知道大家平时定时任务怎么搞,这个系统还没上线,不知道上线会不会有什么坑

    先谢过各位大神

    14 条回复    2017-12-23 23:20:56 +08:00
    xiaoyangsa
        1
    xiaoyangsa  
       2017-12-22 22:07:11 +08:00
    quartz 本来就支持数据库存储吧。线上直接用了 mysql。
    zhx1991
        2
    zhx1991  
       2017-12-22 22:23:30 +08:00
    平台化的定时任务是用数据库存任务, 然后批量拿出来执行

    想添加一个的时候, 服务先把定时任务做成一个可调用的接口, 然后这个定时任务平台上配一下就可以
    zhx1991
        3
    zhx1991  
       2017-12-22 22:27:58 +08:00
    这个东西实现基本功能之后, 就要开始考虑麻烦的运维功能了

    1. 设了一个 1 分钟跑一次的任务, 1 分钟上一个任务没跑完, 正常来讲就不应该再跑下一个任务了, 需要有通知机制告知使用方这里任务执行太慢.

    2. 跑任务业务方会要知道某次任务跑的结果是不是成功, 失败怎么处理, 至少也要通知, 然后再重试? 最大次数?

    3. 因为任务系统是自身独立的, 那么就会有故障. 故障导致某次任务没跑怎么监控, 至少有通知告知业务方某次任务没有执行.

    4. 随时修改执行时间, 查看历史的执行结果之类的功能.
    xuxueli
        4
    xuxueli  
       2017-12-22 23:01:54 +08:00 via Android
    Jverson
        5
    Jverson  
    OP
       2017-12-23 09:37:06 +08:00
    @xiaoyangsa 对,线上用 mysql,为了方便别人跑 demo 这里就用了内存数据库
    Jverson
        6
    Jverson  
    OP
       2017-12-23 09:48:40 +08:00
    @zhx1991 感谢回复~
    1. quartz 应该可以配置相应的策略,DisallowConcurrentExecution
    2. 个人觉得 quartz 只负责通知业务执行,不关心业务的执行结果,失败重试需要业务自己实现,最大程度的解耦
    3. quartz 任务数据是持久化到数据库的,重启后可以设置相应的 misfire 策略,如果不是长时间宕机应该问题也不大
    4. 随时修改执行时间已实现,查看历史执行可以对触发消息做一个记录
    hantsy
        7
    hantsy  
       2017-12-23 11:32:49 +08:00
    一直用 Spring Batch。。。Spring Batch 有官方 ADMIN UI ( spring-batch-admin, 有传统 MVC/Freemark 模板和 AnguarJS 两种 UI ), 不过官方的 spring-batch-admin 现在好像是不怎么维护了,精力全部转向了 Spring Cloud Data Flow。

    看过不少所谓的任务管理系统(工具),基本上都是粗犷的结果(整体的失败或者成功),根本就无法用。连一个最基本的问题都没还解决,比如批处理文件读取数据,到某一行时由于某些原因失败了,Resume 的时候怎么从失败的那一行开始?这些都可以在 Spring Batch 中有很好的解决,文件哪一行,SQL 执行到哪一行,都会有记录,而且 Resume 不需要人工干预的。
    hantsy
        8
    hantsy  
       2017-12-23 11:38:46 +08:00
    当然 Java EE 在上个版本 Java EE 7 ( 2013 年) 也加入了 Batch 标准,只是我现在还没用过。Spring Batch 3 本身就支持 Batch 标准。

    现在都 Spring Batch 4,只可惜这个版本基本上只是基础跟随最新 Spring 基线升级,只没引入我所期待 Reactive。
    hantsy
        9
    hantsy  
       2017-12-23 11:45:27 +08:00
    再一个基础的问题,不知道你的线程怎么处理?见过一些方案都是后台加线程去执行新任务,然后根本不管了,最终会导致服务器直接挂了。
    zhx1991
        10
    zhx1991  
       2017-12-23 14:07:45 +08:00
    @Jverson 执行失败业务有可能没法自己重试, 比如执行机器宕机, 网络故障等等. 如果业务还要对这种场景做容灾, 那就把定时任务的逻辑一部分挪到业务上了.
    Jverson
        11
    Jverson  
    OP
       2017-12-23 18:15:53 +08:00
    @hantsy 感谢回答
    spring batch 没用过,大概知道是一个批处理框架,您提到的批处理文件读取数据失败 resume 的问题我感觉应该是批处理要解决的问题,quartz 我们只是用来做调度
    您提到线程的问题,quartz 使用线程池来管理 job 线程,可以设置线程数量,而且线程唯一要做的事就是通过 mq 触发任务,感觉这里应该不会有什么问题,不知道我理解的对不对
    Jverson
        12
    Jverson  
    OP
       2017-12-23 18:22:10 +08:00
    @zhx1991 因为使用 mq 异步触发任务执行,可以采用应答模式,如果业务执行失败或者宕机则不会返回应答,这样消息便不会被从队列删除,可以分发到其它机器或者等待应用重启后继续消费
    hantsy
        13
    hantsy  
       2017-12-23 20:19:15 +08:00
    @Jverson
    1. 对于 Scheduling,Spring 提供了 Annotation 声明或者 Programmatic 方式,基于 JDK 实现。
    2. Spring Batch 提供一套高级任务管理,只需要实现其简单的 Batchlet(简单任务)或者高级 ETL 形式的基于 Chunk 的批处理(各种 Reader, Processor, Writer) 接口,调度过程完全由 Spring Batch 框架负责。

    以前的一些经历,大部分定时都是与批处理任务相关,比如生成报告,按时统计,对帐等。我基本不会把这两者分开来看。
    Jverson
        14
    Jverson  
    OP
       2017-12-23 23:20:56 +08:00
    @hantsy
    1. spring 提供的 schedule 我也在 demo 中使用过,但是集群环境下需要自己解决多次触发的问题,虽然使用很简单,感觉还是没有 quartz 功能强大
    2. 看来我需要好好研究一下 spring batch,目前还没用过,感觉从功能上好像完全可以替代其它调度系统,不知道实际项目应用中有哪些需要注意的地方
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3367 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 11:27 · PVG 19:27 · LAX 03:27 · JFK 06:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.