用 springboot 和 quartz 撸了一个动态管理定时任务系统 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Jverson
V2EX    Java

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

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

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

    地址: https://github.com/jiwenxing/spingboot-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     Solana     5604 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 01:35 PVG 09:35 LAX 18:35 JFK 21:35
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86