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

关于设置一个定时任务还是多个定时任务问题

  •  
  •   garyxi24 · 2022-08-18 18:48:05 +08:00 · 2311 次点击
    这是一个创建于 829 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题,楼主最近做了一个需求,可以简要概括为:我有一张活动表,数据量不会很大,一年下来能有一百条不错了,然后这其中有些活动会定时开始,开始时间各不相同,到秒这个级别,这种情况是做一个定时任务扫全表对时间好还是创建多个定时任务执行好。

    如果延展开来只是到分钟这个级别或者数据量很大,考虑用哪种方式会更好呢?希望有大佬帮忙分析解答一下。

    PS:目前用的 job 框架是 quartz 。
    第 1 条附言  ·  2022-08-26 11:03:14 +08:00
    谢谢大家的回复,最近比较忙,其实对于我这点数据量我知道怎么折腾都玩得转,业务需求上也不是非得要到秒级别,这个再跟产品 argue 。
    本帖的目的更多的是想讨论延展到更复杂的情况,主要是我对 quartz 内部实现原理不太了解,我是这么猜测的(如有不对的地方请指正):如果多个 job 是开多个线程处理,那几百条数据线程数估计也会很多,当然我估计大部分也会复用;另一方面单 job 扫表的实现,我是不太放心数据库扫的速度,生怕触发时间过了😂(当然我这里指的是如果数据量非常大的情况)。
    17 条回复    2022-08-23 14:09:44 +08:00
    Hug125
        1
    Hug125  
       2022-08-18 21:04:52 +08:00 via iPhone
    比较好奇是什么业务场景的活动要精确到秒级别开始
    实现建议 每天扫描一次,使用 rocket Mq 收费版的延迟消息 将今天要开始的活动放到 mq 里设置上延迟时间

    收费版 Mq 支持自定义时间的延迟消息,开源版只支持等级设置
    potatowish
        2
    potatowish  
       2022-08-18 21:18:15 +08:00 via iPhone
    RabbitMQ 延迟消息就可以满足,免费
    kkeep
        3
    kkeep  
       2022-08-18 21:27:35 +08:00 via Android
    1 个就得了,几百个数据,
    Jojoy
        4
    Jojoy  
       2022-08-18 21:58:45 +08:00
    这个头像这张专辑挺好听的,后来收藏的歌单找不到了就一直想不来这个叫什么名字了;
    今天终于又看到了终于能把专辑添加回来了...
    zmal
        5
    zmal  
       2022-08-18 23:17:44 +08:00
    不知道为嘛 V2EX 有一个风气,很小的需求非劝人上 MQ 上 ES 之类。

    这点数据量用哪个方案区别不大。如果嫌扫表太频繁,1 小时扫一次,把未来 1 小时需要执行的任务加载到定时 job 。甚至可以把所有数据放缓存,变成纯内存操作。如果主表有写入,异步线程更新到缓存。
    Jooooooooo
        6
    Jooooooooo  
       2022-08-18 23:22:59 +08:00   ❤️ 1
    一分钟扫一次表足够了. 把要开始的任务找到.

    如果你"真的"需要秒级别的精准度, 那用 delayQ 是更好的方案 (这当然最底层依然是个轮训的定时任务来实现的, 实际上只要是定时开始的功能, 都是轮训实现的, 只是谁去轮训的问题
    yoloMiss
        7
    yoloMiss  
       2022-08-19 00:52:42 +08:00
    @Jooooooooo 基于 6 楼的意见,有个不成熟的想法(没具体实践过)。quartz 是支持扫表添加定时任务的。可以做个变种。有一个任务每天扫一下。然后根据扫描出来的时间在进行定时任务设置的。
    mejee
        8
    mejee  
       2022-08-19 08:10:51 +08:00
    一个任务扫表就行了。数据库建立一个:status + startTime 的索引,每秒扫描一下 状态是未处理的任务,如果当前时间大于 startTime ,就执行更改状态就完了
    tedzhou1221
        9
    tedzhou1221  
       2022-08-19 08:56:29 +08:00
    设置一个定时任务每半小时跑一次, 获取最近关小时内将要开始的活动的数据出来,放到一个秒级(或 1 分钟)执行一次的定时执行器中。
    xaplux
        10
    xaplux  
       2022-08-19 08:58:09 +08:00   ❤️ 1
    如 5 楼所说,没必要上中间件,可以参考订单过期自动取消实现,采用语言自带的延迟队列即可,比如 Java 可以使用 delayQueue ,每次程序重启记得从数据库扫描出未开始的活动再放一下延迟队列就好了
    tedzhou1221
        11
    tedzhou1221  
       2022-08-19 08:58:38 +08:00
    可参考 xxl-job 的定时任务实现。原理差不多。每秒执行一次的执行器,xxl-job 是用自己 map + list 类型时间轮的东西。我自己是直接用 netty 的时间轮。
    james2013
        12
    james2013  
       2022-08-19 09:52:00 +08:00
    这么少的数据量,一个定时任务,设置为每秒钟执行一次,扫描全表就可以了
    zhady009
        13
    zhady009  
       2022-08-19 10:13:59 +08:00
    如果有用 redis 的话可以考虑上 redisson 有分布式的定时器调度
    joesonw
        14
    joesonw  
       2022-08-19 10:22:20 +08:00 via iPhone
    中间有变化吗?启动时一起加载进来,用定时器呗。
    wolfie
        15
    wolfie  
       2022-08-19 11:35:38 +08:00
    几百条数据,每秒扫一遍都没事。
    百万条数据,任务开始时间做好索引,每秒扫都没事。
    securityCoding
        16
    securityCoding  
       2022-08-19 17:07:16 +08:00 via Android
    几百条数据,随便你怎么扫,扫挂了算我输
    ThreeK
        17
    ThreeK  
       2022-08-23 14:09:44 +08:00
    我也支持 隔一段时间取一批数据放到内存里操作 的方案。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6088 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 02:41 · PVG 10:41 · LAX 18:41 · JFK 21:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.