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