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

2021-03-24 16:56:51 +08:00
 WillingXyz
普通业务 比如 修改内容后发送 mq 同步到 es 。
经历的公司里都不管消息是否发送成功,失败就失败了
6392 次点击
所在节点    程序员
32 条回复
codingadog
2021-03-25 06:39:56 +08:00
@v2exblog 不好意思,错误地 @了
dbpe
2021-03-25 09:16:28 +08:00
说到补偿..我想知道..有没有一种可能(其实就是业务 Bug).就是 mq 端认为消息已达,但实际上数据库并没有变更...这种如何发现?(我听闻大公司有类似数据校验组?那么是不是类似这种去做的?
supermoonie
2021-03-25 09:39:03 +08:00
先入库,状态为待处理,生产者发送消息,消费者处理消息,消费者远程调用更新状态为已完成。定时任务查询未完成记录,并再次发送消息。消费者做幂等处理。
winnie2012
2021-03-25 10:27:16 +08:00
同步写消息表,异步读取 消息表 binlog,做消息消费。
CoderGeek
2021-03-25 11:39:12 +08:00
我们都是事务消息
brucedone
2021-03-25 11:48:57 +08:00
生产者 -> 超时重传,最大重试次数

消息队列 -> 多点节,多副本,高可用

消费者 -> ACK,使用唯一 ID,另外是消息幂等性
demobin
2021-03-25 14:07:44 +08:00
durable
retry
confirm
mannual ack
db
batch job
xxxyh
2021-03-25 15:20:30 +08:00
26 楼加 1,生产者:重试加 ack,broker:多副本,消费者:db 持久化位移之后提交位移,如果是写 es 的话只保证不丢,不保证不重复,如果消费者的任务是写 mysql 的话,和位移的持久化放到一个事务,可以保证恰好一次
xx6412223
2021-03-25 15:25:27 +08:00
把 mq 当作一个服务,调用失败的话就报错呗,
mq 有死信队列
消费者发送 ack 。

够用了
bthulu
2021-03-25 16:10:45 +08:00
@xx6412223 这样不行的, 调用成功并不是代表真的成功了. 死信队列局限性很大的, 大多数网络异常, 死信队列都无能为力. 最简单的, 你先死循环发数据, 然后本地网络适配器里禁用网络再启用网络, 你会发现禁用瞬间, rabbitmq 并不能立即发现网络失效, 数据能照常发送. 要过一段时间, 通常是十几秒到几十秒, rabbitmq 才发现网络失效抛出异常. 那么这个十几秒到几十秒之间发出去的数据, rabbitmq 客户端认为发出去了, 而服务器并不会收到, 如何进死信队列?
对 rabbitmq 来说, 只有服务端 ack 了的才算成功了, 服务 nack 的算发送失败,
还有一种情况是, 长时间既未收到服务端 ack 信号又未收到服务端 nack 信号, 这种数据有可能发送成功了, 也有可能发送失败了.
如果要求一条不丢, 那么在收到服务器 ack 信号时标记这条数据发出去了. 再新起一个守护线程, 定期将已发送但尚未未标记发送成功的数据重发一次.
useben
2021-03-25 21:54:17 +08:00
一句话总结
重试+重试队列+mq 持久化+ack+confirm+幂等性+打 log+定时补偿
cheng6563
2021-03-26 10:03:39 +08:00
发出去的同时往 db 存一个

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

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

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

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

© 2021 V2EX