前言
消息中间件的可靠性消息传递,是消息中间件领域非常重要的方案落实问题(在这之前的MQ理论,MQ选型是抽象层次更高的问题,这里不谈)。
并且这个问题与日常开发是存在较大的关联的。可以这么说,凡是使用了MQ的,机会都要考虑这个问题。当然也有一些原始数据采集,日志数据收集等应用场景对此没有过高要求。但是大多数的业务场景,对此还是有着较高要求的。比如订单系统,支付系统,消息系统等,你弄丢一条消息,嘿嘿。
网上对于这方面的博客,大多从单一MQ,或者干脆就是在论述MQ。我不喜欢这样的论述,这样的论述太过局限,也过于拖沓。
这次,主要从理论方面论证消息的可靠性传递的落实。具体技术,都是依据这些理论的,具体实现都差不多。不过为了便于大家理解,我在文中会以RabbitMq,Kafka这两个主流MQ稍作举例。
在日常开发中,我更倾向于在具体开发前,先整理思路,走通理论,再开始编码。毕竟,如果连理论都走不同,还谈什么编码。
另外,我按照消息可靠性层次逐步推进,形成相应的目录,希望大家喜欢(因为我认为,相较网上这方面现有博客的目录,这样的目录更合理,更人性化)。
概述
这里简单谈一些有关消息可靠性传递的理论。
消息传递次数
消息在消息系统(生产者+MQ+消费者),其消费的次数,无非一下三种情况:
最多一次最少一次不多不少一次消息可靠性层次
这也代表着消息系统的消息可靠性的三个层次:
最多一次:上游服务的消息发出了,至于下游能不能收到服务,就不管了。结果就是下游服务,可能根本就没有接收到消息。最少一次:上游服务的消息发出了,并通过某些机制,确保下游服务一定收到了该消息。但是收到了几次,就不管了。结果就是下游服务,可能多次收到同一条消息。不多不少一次:上游服务的消息发出了,并确保下游服务一定收到了消息。下游服务通过某些机制,确保多次收到该消息与单次收到该消息,对其系统状态的影响是相同的。方案落实
实现上述三个层次,需要逐步从三个方面考虑:
最多一次:会用消息队列即可,只要确保消息的连通性即可最少一次:通过MQ提供的确认机制,确保消息的传递不多不少一次:通过外部应用程序,确保消息的单次消费与多次消费对系统状态影响是一致的上述三个层次,对系统的性能损耗,系统复杂度等都是逐步上升的。
当然,我们首先,需要了解这三个层次分别如何实现。
再在实际开发中,根据需要,灵活选取合适方案。
最多一次的消息传递
这个方案是最简单的,只要确保消息系统的正确运作,以及系统的连通性即可。在正常情况下,可以保证绝大部分数据的可靠性传递。但是仍旧存在极小数据的丢失,并且数据的丢失会因为消息队列的选择,以及消息并发量,而受到影响。
优点
实现简单。只要搭建对应的MQ服务器,写出对应的生产者与消费者,以及相应配置,即可正常工作。缺点
无法保证数据的可靠性,会存在一定的数据丢失情况,尤其是在并发量较大时实际应用
可以应用于日志上传这样对消息可靠性要求低的应用场景。
总结
如果数据量不大的情况下,推荐使用RabbitMQ,其消息可靠性在地数据量下,是最可靠的。但是在达到万级并发时,会存在消息丢失,丢失的比例可以达到千分之一。
如果数据量较大的情况下,要么采用集群。要么就采用Kafk(Kafka可支持十万级并发)
一般来说,这种消息可靠性多见于项目初建,或类似日志采集,原始数据采集这样的特定场景。
最少一次的消息传递
这个方案开始利用MQ提供的特定机制,来提高消息传递的可靠性。
优点
不错的消息可靠性。确保不会出现消息丢失的情况实现并不复杂。只需要合理使用MQ的API,设置合理参数(如重试次数)即可缺点
会出现消息重复消费的情况参数的设置需要合理。如重试次数,一般设置为5次,也可根据情况,进行调整资源占用的提升。如带宽(每次消息成功生产,消费都需要返回一条数据进行确认)等方案落实
该方案的实现组成,由以下三个方面构成:
消息的可靠生产消息的可靠存储消息的可靠消费通过以上三个方面的落实,确保可消息一定被下游服务消费。
消息的可靠生产
消息的可靠生产,是通过回调确认机制,确保消息一定被消息服务器接收。
消息生产,发送给消息服务器后,消息服务器会返回一个确认信息,表示数据正常接收。
如果生产者在一定时间内没有接收到确认信息,就会触发重试机制,进行消息的重发。
如RabbitMq的