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

请教:延时任务有没有好的开源工具,最好是 golang 的?

  •  
  •   excxapp · 2020-04-22 13:07:27 +08:00 via Android · 3720 次点击
    这是一个创建于 1674 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 可以延时执行任务
    • 性能不错
    • 可以取消任务
    • 可以更改任务执行时间,比如我定时后系统更新了这个任务更新任务时间
    • 组延时任务,例如,可以实现类似支付宝支付通知 1-3-120…等秒后通知,触发后消费确认后可以取消组延时定时
    17 条回复    2020-04-22 22:20:49 +08:00
    Hanggi
        1
    Hanggi  
       2020-04-22 13:11:44 +08:00
    这不是事件驱动吗
    SingeeKing
        2
    SingeeKing  
       2020-04-22 13:13:22 +08:00
    这不是消息队列吗
    excxapp
        3
    excxapp  
    OP
       2020-04-22 13:15:46 +08:00 via Android
    @SingeeKing #2 延时版本消息队列应该,但是组延时和修改延时这个没发现有实现的
    so1n
        4
    so1n  
       2020-04-22 13:30:09 +08:00
    基于 redis zset 就可以做一个了
    labulaka521
        5
    labulaka521  
       2020-04-22 13:39:22 +08:00 via Android
    想法不错,我觉得可以在我写的定时任务里 https://github.com/labulaka521/crocodile 加上这个功能😉
    charlieputon
        6
    charlieputon  
       2020-04-22 13:42:07 +08:00 via Android
    可以用复方利多卡因凝胶 /丁卡因乳膏
    renyijiu
        7
    renyijiu  
       2020-04-22 13:55:26 +08:00
    https://github.com/bitleak/lmstfy 美图有个基于 redis 做的框架,应该可以达到你的需求,核心就是 redis 的 zset 操作
    excxapp
        8
    excxapp  
    OP
       2020-04-22 14:23:06 +08:00
    我之前用的 beanstalkd 的延时队列做的延时任务,外加自己手动过滤,但是考虑这样效率会比较低,
    想知道用什么方法可以实现主要的 2 点:
    可以更改任务执行时间,比如我定时后系统更新了这个任务更新任务时间
    组延时任务,例如,可以实现类似支付宝支付通知 1-3-120…等秒后通知,触发后消费确认后可以取消组延时定时
    @renyijiu
    @charlieputon
    @so1n zet 可以实现队列感觉不怎么高效,组的这个好想没办法用这个实现。
    PiersSoCool
        9
    PiersSoCool  
       2020-04-22 14:23:34 +08:00
    我实践过,其实你这是两套东西,一个是任务存储,另一个是任务执行。这里只讨论任务执行。
    原生 timer + context,很容易实现你这一套。
    1 、timer 延迟
    2 、性能自己控制,benchmark 可测
    3 、传入 context,不需要 cancel 掉,启动时候检测 context
    4 、建议不要更改执行时间,而是删除之前的任务进行重建,更改这种操作实现太复杂
    5 、多个 timer 同时跑

    这个是我在目前公司实现的,没有任何问题,简单方便。不建议框架,没必要。
    excxapp
        10
    excxapp  
    OP
       2020-04-22 14:26:00 +08:00
    @labulaka521 不错,你这个实现原理是 go tickb 吧,网上说用时间轮方式会更好,不知道咋样,没试过,你有试过吗?
    excxapp
        11
    excxapp  
    OP
       2020-04-22 14:30:47 +08:00
    @PiersSoCool 更改任务我是看了 redis 的有序列表可以实现,所以也没考虑这么多,确实删除新添加会好一些,其实这个底层实现,外层暴露应该还是修改,只是内部是删除后修改。
    组这个怎么实现,微信支付和支付宝支付都可以实现,例如微信下面的方式,有返回后会取消后面的通知,难道是支付完成后建立这么多消息队列,然后第三方系统确认支付结果后,再依次取消掉吗?
    以下为微信文档上面说的:后台通知交互时,如果微信收到商户的应答不符合规范或超时,微信会判定本次通知失败,重新发送通知,直到成功为止(在通知一直不成功的情况下,微信总共会发起多次通知,通知频率为 15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m ),但微信不保证通知最终一定能成功
    renyijiu
        12
    renyijiu  
       2020-04-22 14:32:42 +08:00
    @excxapp #8 zset 效率低下是什么概念呢?组延时可以业务逻辑解决,延时后判断条件,未达到重新计算延时时间扔回队列
    excxapp
        13
    excxapp  
    OP
       2020-04-22 14:39:21 +08:00
    @renyijiu 不是 zset 效率低,是用 zset 做延时消息队列效率没那么高效吧
    这个是网上有个人发的>>>所以使用 zrange 这个命令去范围获取,平均的时间复杂度就是 O[(LogN)+M],最坏的情况 O(n)<<<
    PiersSoCool
        14
    PiersSoCool  
       2020-04-22 14:44:28 +08:00
    @excxapp 微信这个场景相对容易些,失败之后再次设置 timer 即可,否则就是成功了,这个思路我是参考 JS 时间驱动的模型(楼上有位仁兄说得好,事件驱动模型,有的时候 JS 真是让人又爱又恨)。巧了,我任务的持久化确实是用 Redis list 做的,BLPOPRPUSH 维护两个队列确保任务执行完成。
    labulaka521
        15
    labulaka521  
       2020-04-22 15:25:14 +08:00
    @excxapp 没,时间轮询我觉的有可能出现延迟,
    jerrwy
        16
    jerrwy  
       2020-04-22 16:37:49 +08:00
    可以基于 redis 过期 key 通知做
    toboro
        17
    toboro  
       2020-04-22 22:20:49 +08:00
    延时工具 go-viagra
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5716 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 01:42 · PVG 09:42 · LAX 17:42 · JFK 20:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.