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

一个回调的业务问题

  •  
  •   dackh ·
    dackh · 2019-09-17 17:21:50 +08:00 · 2498 次点击
    这是一个创建于 1892 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景

    类似于微信支付,调用方来我这里要数据,并给我回调接口,我将数据通过回调接口推送回去

    问题

    我按任务存储请求记录,当调用方给的回调接口异常的时候,那么我数据永远推送不回去,该任务将会一直推送,为脏数据

    但是调用失败也可能为其他网络问题,那么该如何进行区别呢?如何进行处理?

    13 条回复    2019-09-18 15:16:07 +08:00
    awanabe
        1
    awanabe  
       2019-09-17 17:30:43 +08:00
    重试三次...不行就置为失败
    MarkOrca
        2
    MarkOrca  
       2019-09-17 17:35:15 +08:00
    加个计数器
    dp2px
        3
    dp2px  
       2019-09-17 17:36:05 +08:00
    我先声明一下,我不是做后台的,我认为要做的好一点应该有一个排队策略,把一些失败的加入队列然后根据次数,依次增加请求间隔,当队列的数据超过一定数量就要报警了,可能网络或者服务器已经断开或宕机很久了,应该通知运维人员处理。原理就有点像三级四级缓存一样,分级别的事件队列。
    memedahui
        4
    memedahui  
       2019-09-17 17:38:30 +08:00
    我就不明白了,调用方来你调用你的接口,为什么还要给你回调接口.你直接返回给他不就行了吗?
    lllllliu
        5
    lllllliu  
       2019-09-17 17:39:01 +08:00
    你可以阶梯通知呀。根据的你场景设置一个频率和对于的阈值,比如 1 分钟内 1 秒一次,10 分钟内 1 分 1 次,然后就按小时通知,当次数大于多少次的时候就归档做失败处理呗。
    LongMaoz
        6
    LongMaoz  
       2019-09-17 17:39:42 +08:00
    @memedahui 应该是异步处理的,没办法直接从接口返回
    lllllliu
        7
    lllllliu  
       2019-09-17 17:40:07 +08:00
    @memedahui 有些业务和事务场景不能立即返回,比如楼主说的微信支付,就需要在微信的 notify 里处理订单是不是真的被支付了。
    dackh
        8
    dackh  
    OP
       2019-09-17 17:58:44 +08:00
    @lllllliu 我的想法是按 15s,15s,1min,3min,10min,30min,30min...这种频率来回调,超过一天即判定失败
    DebugTy
        9
    DebugTy  
       2019-09-17 18:02:07 +08:00
    一般来说异步回调最好可以结合主动查询来做, 楼上几位提供了一些重试策略,其实一般来说重试也很难成功, 可以把数据持久化到 db 中,可以再用 job 去跑, 实在不行可以人工介入
    jaynos
        10
    jaynos  
       2019-09-17 18:29:26 +08:00
    基于楼上的做法, 可以再补充一点就是记录个最后一次回调时间, 回调条件是<最近一天内的><最后一次回调在半小时之前的(可以采用阶梯的方式, 1m, 3m, 10m, 30m, 1h, 3h, 5h)>
    annielong
        11
    annielong  
       2019-09-17 18:39:06 +08:00
    可以看看微信的 notify 是如何处理的,不过思路上也是如果失败就多送几次,前几次间隔短些,越往后越间隔长些,超多一定次数或者时间就不再送,
    hspeed18
        12
    hspeed18  
       2019-09-17 21:39:15 +08:00
    重试+人工对账
    Evilk
        13
    Evilk  
       2019-09-18 15:16:07 +08:00
    最近刚好在做类似这样的东西,即,支付结果异步阶梯性通知
    server:PHP
    MQ:rabbitMQ

    1.请求方请求接口,在接口处,将本次请求的业务数据(包含请求方的 notify)发送到队列 queueA,消费者 consumer 监听此队列
    2.一旦有消息入队,则开始消费(此时是第一次消费,这里的消费就是通知请求方的 notify)
    3.如果 notify 返回结果正常,则手动 ack,告诉 MQ 删除此消息
    4.如果 notify 返回结果不正常,则将此消息计数 1,将此消息设置过期时间为 10s,并投递到延时队列 queue1,此处 queue1 为延时队列,超过 10s 后,会自动重新投递消息到 queueA
    5.当 consumer 再次消费到这个消息时,如果还是不正常,则将此消息计数 2,将此消息设置过期时间为 20s,并投递到延时队列 queue2,此处 queue2 为延时队列,超过 20s 后,会自动重新投递消息到 queueA
    ...
    当消息的计数超过上限后,则不再投递到延时队列中,而是投递到专门的失败队列中,做进一步的处理
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5327 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 08:36 · PVG 16:36 · LAX 00:36 · JFK 03:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.