春招面试复习:消息队列(四)- 消息可靠性投递的实现原理

丢失消息则丢了数据,这是我们不能接受的,否则MQ意义何在?

因此主流MQ其实都提供了可靠性投递机制,确保即使网络异常,消息也能可靠传递,而不会丢失。

如果发现还是丢失消息了,多半是开发者问题,很可能没有正确配置MQ。不同MQ在保证消息可靠传递方面的实现原理其实也是一样的。

1 验证丢失的消息

大公司一般都通过分布式链路追踪系统,很方便追踪每条消息。
如果是中小公司,也有个简单方案验证。即利用MQ的有序性:

  1. 在Producer端,给每个发出的消息附加一个连续递增的序号
  2. 然后在Consumer端检查这序号的连续性
  • Consumer收到消息序号严格递增,则无消息丢失
  • 若存在序号不连续,则丢了消息
    通过缺失的序号还能确定到底丢失的哪条消息

大多MQ客户端支持拦截器,可在Pro发消息前的拦截器中注入序号到消息中,在Con收消息的拦截器中检测序号连续性。

  • 好处
    消息验证代码不会侵入业务代码。系统稳定后也方便将验证逻辑关闭/删除。

分布式系统下实现验证方法,须注意:

  • Kafka、RocketMQ不保证在Topic上的严格顺序,只保证分区上的消息有序,所以在发消息时须指定分区。且在每个分区单独验证消息序号连续性。

如果系统的Producer多实例,由于并不好协调多Producer之间的发送顺序,所以也需要每个Producer分别生成消息序号,且需要附加Producer标识,在Con端按每个Pro分别验证序号连续性。

Consumer实例数量最好和分区数量一一对应,如此便可方便在Con内验证消息序号连续性。

2 确保消息可靠传递

有小伙伴要问了,到底哪些地方会导致丢消息,又该如何避免呢?

  • 消息从生产到消费完成的阶段

2.1 生产阶段

在Producer创建消息出来,通过网络传输发送到Broker。

MQ通过最常用的请求确认机制保证消息可靠传递:
调用发消息方法时,MQ客户端把消息发至于Broker,Broker收到后,给客户端返回确认响应,表明已收。客户端收到响应后,完成一次正常消息的发送。

只要Pro收到Broker的确认,即可保证消息在生产阶段不会丢失。

  • 有些MQ长时间未收到发送确认响应后,会自动重试
  • 若重试失败,以返回值或者异常方式通知用户

写发消息代码时,注意正确处理返回值或捕获异常,即可保证该阶段消息不会丢失。

示例

以Kafka为例看可靠发送消息:

同步发送时,只要注意捕获异常即可。

try {
   
    RecordMetadata metadata = producer.send(record).get()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值