大数据开发:消息队列如何确保消息不丢失

消息队列在大数据技术生态当中,一直都是值得重视的存在,开源的消息队列产品,市面上也不少,基于不同的场景,需要去匹配不同的解决方案。围绕消息队列,今天的大数据开发学习分享,我们主要来聊聊,消息队列如何确保消息不丢失。

1、检测消息丢失的方法

可以利用消息队列的有序性来验证是否有消息丢失。在Producer端给每个发出的消息附加一个连续递增的序号,然后在Consumer端来检查这个序号的连续性。如果没有消息丢失,Consumer收到消息的序号必然是连续递增的,如果检测到序号不连续,那就是丢消息了。还可以通过缺失的序号来确定丢失的是哪条消息,方便进一步排查原因。

大多数消息队列的客户端都支持拦截器机制,可以利用这个拦截器机制,在Producer发送消息之前的拦截器中将序号注入到消息中,在Consumer收到消息的拦截器中检测序号的连续性。

如果是在一个分布式系统中实现这个检测方法,有几个问题需要注意:

首先,像Kafka和RocketMQ这样的消息队列,是不保证Topic上的严格顺序的,只能保证分区上的消息是有序的,所以在发消息的时候必须指定分区,并且,在每个分区单独检测消息序号的连续性。

如果系统中Producer是多实例的,由于并不好协调多个Producer之间的发送顺序,所以也需要每个Producer分别生成各自的消息序号,并且需要附加上Producer的标识,在Consumer端按照每个Producer分别来检测序号的连续性。

Consumer实例的数量最好和分区数量一致,做到Consumer和分区一一对应,这样会比较方便地在Consumer内检测消息序号的连续性。

2、确保消息可靠传递

一条消息从生产到消费完成这个过程,可以划分为三个阶段:

生产阶段:在这个阶段,从消息在Producer创建出来,经过网络传输发送到Broker端

存储阶段:在这个阶段,消息在Broker端存储,如果是集群,消息会在这个阶段被复制到其他的副本上

消费阶段:在这个阶段,Consumer从Broker上拉取消息,经过网络传输发送到Consumer上

①生产阶段

在生产阶段,消息队列通过最常用的请求确认机制,来保证消息的可靠传递:当在代码中调用发送消息方法时,消息队列的客户端会把消息发送到Broker,Broker收到消息后,会给客户端返回一个确认响应,表明消息已经收到了。客户端收到响应后,完成了一次正常消息的发送。

只要Producer收到了Broker的确认响应就可以保证消息在生产阶段不会丢失。有些消息队列在长时间没收到发送确认响应后,会自动重试,如果重试再失败,就会以返回值或者异常的方式告知用户。

在编写发送消息代码时,需要注意,正确处理返回值或者捕获异常,就可以保证这个阶段的消息不会丢失。

②存储阶段

在存储阶段正常情况下,只要Broker在正常运行,就不会出现丢失消息的问题,但是如果Broker出现了故障,比如进程死掉了或者服务器宕机了,还是可能会丢失消息的。

如果对消息的可靠性要求非常高,可以通过配置Broker参数来避免因为宕机丢消息。

对于单个节点的Broker,需要配置Broker参数,在收到消息后,将消息写入磁盘后再给Producer返回确认响应,这样即使发生宕机,由于消息已经被写入磁盘,就不会丢失消息,恢复后还可以继续消费。例如,在RocketMQ中,需要将刷盘方式flushDiskType配置为SYNC_FLUSH同步刷盘。

如果Broker是由多个节点组成的集群,需要将Broker集群配置成:至少将消息发送到2个以上的节点,再给客户端回复发送确认响应。这样当某个Broker宕机后,其他的Broker可以替代宕机的Broker,也不会发生消息丢失。

③消费阶段

消费阶段采用和生产阶段类似的确认机制来保证消息的可靠传递,客户端从Broker拉取消息后,执行用户的消费业务逻辑,成功后,才会给Broker发送消费确认响应。如果Broker没有收到消费确认响应,下次拉消息的时候还会返回同一条消息,确认消息不会在网络传输过程中丢失,也不会因为客户端在执行消费逻辑中出错导致丢失。

在编写消费代码时需要注意的是,不要在收到消息后就立即发送消费确认,而是应该在执行完所有消费业务逻辑之后,再发送消费确认。

3、小结

在生产阶段,需要捕获消息发送的错误,并重发消息;

在存储阶段,可以通过配置刷盘和复制相关的参数,让消息写入到多个副本的磁盘上,来确保消息不会因为某个Broker宕机或者磁盘损坏而丢失;

在消费阶段,需要在处理完全部消费业务逻辑之后,再发送消费确认。

关于大数据开发学习,消息队列如何确保消息不丢失,以上就为大家做了基本的介绍了。在现有的大数据生态体系当中,消息队列的开源产品很多,对于主流青睐的产品,也需要大家有相应的了解。

你可能感兴趣的:(大数据开发:消息队列如何确保消息不丢失)