V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
wangxiaoer
V2EX  ›  问与答

如何处理任务意外中断/恢复等情况

  •  
  •   wangxiaoer · 2017-10-19 09:12:28 +08:00 · 2352 次点击
    这是一个创建于 2380 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一些用户提交的耗时任务通常会异步执行,如果程序遇到意外情况停电、应用异常关闭等被终止,这就需要考虑到任务恢复了。

    举个简单例子,用户上传了一个 csv 文件,需要解析并入库,解析到一半左右中断了。一般大家在处理这种情况的时候,在任务执行中都会存储哪些信息,如何存储,恢复?

    如果涉及到集群,是不是考虑的要更多,比如任务的恢复必须由任务的发起方来进行,否则会找不到上传的那个文件,另外也要防止多个节点重复执行。

    这一块想听听业内成熟的做法,尽量轻量化一点。

    对了,后台是 Java 和 NodeJS。

    16 条回复    2017-10-19 14:16:09 +08:00
    MuaGeWang
        1
    MuaGeWang  
       2017-10-19 09:19:49 +08:00
    叫用户再传一遍
    stanjia
        2
    stanjia  
       2017-10-19 09:29:06 +08:00
    @MuaGeWang 让客户端
    wangxiaoer
        3
    wangxiaoer  
    OP
       2017-10-19 09:45:35 +08:00
    重复传不太合适吧
    zhouwei520
        4
    zhouwei520  
       2017-10-19 10:07:29 +08:00
    中断,超时或者失败,rollback,重新执行。

    单系统,停电、应用异常关闭无解的好吧

    智能多服务器多应用
    zhouwei520
        5
    zhouwei520  
       2017-10-19 10:07:45 +08:00
    智能
    zhouwei520
        6
    zhouwei520  
       2017-10-19 10:07:51 +08:00
    只能
    mooncakejs
        7
    mooncakejs  
       2017-10-19 10:10:28 +08:00
    队列一般都有重试机制, 数据导入 能开事务开事务,不能开事务我也不知道。
    wangxiaoer
        8
    wangxiaoer  
    OP
       2017-10-19 10:17:09 +08:00
    @zhouwei520 我的意思就是重新执行一般都需要记录哪些信息?执行中是不是要频发刷新任务进度,进度信息又存放在哪里?假如 90%多的时候异常退出,进度信息也没有持久化,难道从头在开始运行吗?
    hcymk2
        9
    hcymk2  
       2017-10-19 10:22:40 +08:00
    上传和解析不要放在一起。上传成功后就相应前台,之后通过 job 解析入库,成功后通过通知提醒用户。
    gamexg
        10
    gamexg  
       2017-10-19 11:21:04 +08:00   ❤️ 1
    原来做渲染时任务记录直接存数据库。
    原始文件和最终输出都是直接放到云储存。

    任务中间虽然也有几个步骤,但是并没有保存中间状态,失败时重新执行整个任务。

    任务执行每一子任务都有超时时间+心跳。

    超时时间负责解决任子任务卡住的问题,当工作者执行耗时超过预定时间会杀死派生的任务进程强制失败。
    调度器也会检查是否存在严重超时的任务。

    心跳负责解决工作者挂掉的问题,有一个调度器定时检查心跳超时的任务,将这种标记为任务失败。

    被标记为失败的任务会尝试重试 3 次,仍然失败就放弃。


    本来是用任务队列做的,但是由于跨机房,任务队列很容易卡死,最终改为了长轮询。工作者长轮询查询是否存在新任务。数据库锁保证单个任务只分配给单个工作者。

    这种需求任务数量少,单个任务耗时几小时,就不太在乎任务分配的性能了。
    耗时最长的渲染工作是调用外部进程,没办法保存中间进度,也没保存中间状态用来恢复。
    wangxiaoer
        11
    wangxiaoer  
    OP
       2017-10-19 11:27:41 +08:00
    @gamexg 失败重新执行感觉有点不合适,正常一次任务可能要很久的
    gamexg
        12
    gamexg  
       2017-10-19 11:51:41 +08:00
    @wangxiaoer #11 额,任务恢复实现太麻烦了,除非经常失败没必要做吧?
    真的想实现比较好的做法是拆分成子任务,单个子任务挂了重新开始,对其他子任务没影响。
    wangxiaoer
        13
    wangxiaoer  
    OP
       2017-10-19 12:05:47 +08:00
    @gamexg 是的,所以先找一个相对稳妥的办法。
    sujin190
        14
    sujin190  
       2017-10-19 12:38:49 +08:00
    正常情况下,异步任务都应该是做成可重入幂等的啊,这样失败了,任务应该还在啊,重新执行一遍就是了啊,否则,任务多了会很麻烦
    wangxiaoer
        15
    wangxiaoer  
    OP
       2017-10-19 13:45:08 +08:00
    @sujin190 “可重入幂等” 具体怎么讲,能详细说说吗
    sujin190
        16
    sujin190  
       2017-10-19 14:16:09 +08:00
    @wangxiaoer #15 很简单啊,就是相同任务,无论什么情况,无论执行多少遍,结果都一样
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3469 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 11:25 · PVG 19:25 · LAX 04:25 · JFK 07:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.