大佬们,你们公司普通业务里 mq 有做消息可靠性吗?怎么做的

2021-03-24 16:56:51 +08:00
 WillingXyz
普通业务 比如 修改内容后发送 mq 同步到 es 。
经历的公司里都不管消息是否发送成功,失败就失败了
6760 次点击
所在节点    程序员
32 条回复
Jooooooooo
2021-03-24 17:02:12 +08:00
那是很明显数据不重要, 丢一些没关系.

一般这种如果要求一定成功会用失败补偿 /延迟校验 /双通道发送之类的方法减少数据丢失的可能.
joApioVVx4M4X6Rf
2021-03-24 17:04:56 +08:00
纳尼? rabbitmq 有持久化啊
vitoliu
2021-03-24 17:12:52 +08:00
写入重试,打好日志。
再写一个分时段同步 db 数据到 es 的工具。
MQ 出问题了直接调接口补数据。
WillingXyz
2021-03-24 17:15:23 +08:00
@v2exblog 是发送的时候,异步发送
WillingXyz
2021-03-24 17:16:57 +08:00
@Jooooooooo 怎么衡量重不重要呢?比如一些数据同步到 es 失败就搜索不到,感觉也挺重要
Jooooooooo
2021-03-24 17:21:52 +08:00
@WillingXyz 指标定义可以用是否会产生资金损失 /是否会产生客诉 /是否会对目标用户产生负面影响等方面评估, 然后做这些容灾也是需要花钱的, ROI 就得你们自己评估了. 是丢了这些数据造成的损失大, 还是做这些容灾手段付出的成本大.
securityCoding
2021-03-24 17:45:01 +08:00
有做的,订单类业务 mq 丢失后续业务流程全部挂了 ,说说我用的方案吧
rocketmq 用的比较多,拿 rocketmq 来说吧
1. producer client 设置自动重试 3 次,注意发送重试是立即重试(循环),默认 timeOut 是 3 秒
2. producer.send(Message msg,SendCallback sendCallback) 这种是异步发送,但是有 callback 业务可以实时感知发送结果
2. callback 记录日志 ,并捕捉 callback 异常消息持久化至 db(拼接好完整的重试消息 body)
3. 定时器每隔 5 秒扫描一遍待重试的消息,超过最大次数(3)则发送至告警平台人工介入
securityCoding
2021-03-24 17:50:09 +08:00
还有一种方案是 rmq 的事务消息 , 落库前发送一条事务消息 , rmq 会自动来询问注册的回调 listener 消息是否可以发送 , 事务状态一直是 waitting 的话 rmq 会周期性的来回调 listener ,只是时间周期是固定的
timethinker
2021-03-24 18:01:38 +08:00
一般涉及到消息发送都基本上是异步流程了,建议在一个本地事务中将需要发送的消息写入到一个“消息发送表”内,另一个线程定时扫描这张表,然后将消息发送出去,发送完成就可以删掉或标记为已处理,发送失败记录失败次数和异常等原因。
wmhack
2021-03-24 20:25:39 +08:00
@securityCoding 2. 后面两步,是不是可以简化成:只记录日志,日志里包含重试消息的 body,然后用钉钉告警出来呢?
securityCoding
2021-03-24 20:35:41 +08:00
@wmhack 可以的 , 无非是自动与手动的区别.
我的场景是电商订单 , 尽可能的希望这种异常场景程序能自愈而不是直接人工介入
misaka19000
2021-03-24 20:50:00 +08:00
同步失败重做啊
tedzhou1221
2021-03-24 20:50:22 +08:00
上市公司项目,MQ 都只用来发短信、微信。服务调用基本都是同步。这样都能活得下出,消息可不可靠不影响,哈哈
neoblackcap
2021-03-24 23:05:40 +08:00
mq 不能保证其可靠性,但是这消息又很重要,那么就应该实现分布式事务。
一步出错就回滚,日志记录错误。然后慢慢修正错误提高性能
xiang0818
2021-03-24 23:18:32 +08:00
消息重试了解下
Ptu2sha
2021-03-24 23:24:28 +08:00
只要的肯定加确认和重试 都失败进入日志 后期处理
xuanbg
2021-03-25 03:19:30 +08:00
死信队列用起来
fuxiuyin
2021-03-25 03:48:34 +08:00
我觉得这个问题应该分成三个,一个是发送者发送到消息队列可不可靠,一个是消息队列发送给接收者可不可靠,第三个是接收者接收了之后处理的可不可靠。第二个问题不用担心,可以简单相信消息队列保证了“至少一次”。第一个问题简单解决就是发送者先写一个数据库,然后一个线程发,或者发送者弄成全异步的,通过 Task 来 track 一条消息。第三个问题就直接接收者全处理完了再给 mq 回 ack,或者接收者先写个 db 回个 ack 再慢慢处理。这个问题的重点在于不要让消息 lose track,一直能够 track 到就不怕细小的问题,因为随时可以有人来查看恢复。比如,发送流程都很好,接收者成功收到以后挂了,然后消息丢了就不好办了。mq 是一个异步和解耦组件,异步了就要在发送者和接收者都保存一些信息。同步状态下只发送端保存,接收端挂了就挂了,发送端保存了还知道接收者处理哪条消息的时候挂了,于是重来就行了。多说一句,其实点对点的发送接收做异步的话也不一定非得用 mq 啦,可以学异步 rpc 那样发 promise 。发送端发个 promise 就走,接收端把 promise 放到监听对列。发送端啥时候闲了,或者 promise 太多了,或者其他线程,去发 promise 的实际内容,接收端等哪个 promise 好了就处理好的那个。
fuxiuyin
2021-03-25 03:54:58 +08:00
@fuxiuyin 发出去了发现最后那个少了一点,要求接收端给回应的话,就是两边互发 promise 。发送端发个 promise,接收端收到以后回个结果的 promise,然后两边异步等 promise,balanala 。
codingadog
2021-03-25 06:39:18 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/764715

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX