本文参考:《RocketMQ技术内幕》 书籍不错,作为一个读者推荐购买
目前我所接触并常用的消息中间件 kafka,RocketMQ,rabbitmq
kafka主要用于公司日志收集,RocketMQ,用于公司中的金融以及支付业务,rabbitmq,用于公司初创的团队的一些单体应用的业务。我们为什么要用消息中间件,以及如何选择消息中间件,他的优缺点对比是什么,只有做到了架构,以及深入比较才能根据实际情况来做出选择。
设计理念
RocketMq设计基于主题的发布与订阅模式,其核心功能包括消息发送,消息存储(Broker)、消息消费,整体设计追求简单与性能第一,主要提现在如下三方面。
首先,NameServer设计极其简单,摒弃了业界常用的使用Zookeeper 充当信息管理的“注册中心”,而是自研NameServer来实现元数据的管理(Topic 路由信息等)。从实际需求出发,因为Topic路由信息无需在集群之间保持强一致,追求最终一致性,并且能容忍分钟级别的不一致。正式基于此种情况,RocketMq的NameServer集群之间互不通信,极大的降低了NameServer实现的复杂程度,对网络的要求也降低了不少,当然性能相比较Zookeeper有了极大的提升。
其次是高效的IO存储机制。RocketMq追求消息发送的高吞吐量,RocketMq的消息存储文件设计成文件组的概念,组内单个文件大小固定,方便引入内存映射机制,所有主题的消息存储基于顺序写,极大的提供了消息写性能,同时为了兼顾消息消费与消息查找,引入了消息消费队列文件与索引文件。
最后容忍存在设计缺陷,适当将某些工作下放给RocketMq使用者。消息中间件的实现者经常会遇到一个难题:如何保证消息一定能被消费者消费,并且保证只消费一次。RocketMQ的设计者给出的解决方案是不解决这个难题,而是退而求其次,只保证消息被消费者消费,但设计上允许消息重复消费,这样极大的简化了消息中间件的内核,使得实现消息发送高可用变得简单高效,消息重复问题由消费者在消息消费时实现幂等。
1.3.2设计目标
RocketMQ作为一款消息中间件,需要解决如下问题:
1.架构模式
RocketMQ与大部分消息中间件一样,采用发布订阅模式,基本的参与组建主要包括:消息发送者,消息服务器(消息存储)、消息消费、路由发现。
2.顺序消息
所谓顺序消息,就是消息消费者按照消息达到消息存储服务器的顺序消费。RocketMQ可以严格保证消息有序。
3.消息过滤
消息过滤是指在消息消费时,消息消费者可以对同一主题下的消息按照规则只消费自己感兴趣的消息。RocketMQ消息过滤支持在服务端与消费端的消息过滤机制。
1)消息在Broker端过滤。Broker只将消息消费者感兴趣的消息发送给消息消费者。
2)消息在消息消费端过滤,消息过滤凡是完全由消息消费者定义,但缺点是有很多无用的消息通过Broker传输到消费端。
4.消息存储
消息中间件的一个核心实现是消息的存储,对消息存储一般有如下两个维度的考量:消息堆积能力和消息存储性能。RocketMQ追求消息存储的高性能,引入内存映射机制,所有主题的消息顺序存储在同一个文件中。同时为了避免消息无限在消息存储服务器中积累,引入了消息文件过期机制与文件存储空间报警机制。
5.消息高可用
通常影响消息可靠性的有以下几种情况。
1)Broker正常关机。
2)Broker异常Crash
3)OS Crash
4) 机器断电,但是能立即回复供电情况
5)机器无法开机(可能是CPU、主板、内存等关键设备损坏)
6)磁盘设备损坏
针对上述情况,情况1~4的RocketMQ在同步刷盘机制下可以确保不丢失消息,在异步刷盘模式下,会丢失少量消息。情况5~6属于单点故障,一旦发生,该节点上的消息全部丢失,如果开启了异步复制机制,RocketMQ能保证只丢失少量消息,RocketMQ在后续版本中将引入双写机制,以满足消息可靠性要求极高的场合。
6消息达到(消费)低延迟
RocketMQ在消息不发生消息堆积时,以长轮训模式实现准实时的消息推送模式。
7.确保消息必须被消费一次
RocketMQ通过消息消费确认机制(ACK)来保证消息至少被消费一次,但由于ACK消息有可能丢失等其他原因,RocketMQ无法做到消息只被消费一次,有可能重复消费的可能。
8.回溯消息
回溯消息是指消息消费端已经消费成功的消息,由于业务要求需要重新消费消息,RocketMQ 支持按实际回溯消息,时间维度可以精确到毫秒,可以向前或者向后回溯。
9.消息堆积
消息中间件的主要功能是异步解耦,必须具备应对前端的数据洪峰,提高后端系统的可用性,必然要求消息中间件具备一定的消息堆积能力。RocketMQ消息存储使用磁盘文件(内存映射机制),并且在物理布局上为多个大小相等的文件组成逻辑文件组,可以无限循环使用。RocketMQ消息存储文件并不是永久存储在消息服务器端,而是提供过期机制,默认保留3天。
10.定时消息
定时消息是指消息发送到broker后,不能被消息消费端立即消费,要到特定的时间点或者等待特定的时间后才能被消费。如果要支持任意精度的定时消息消费,必须在消息服务端对消息进行排序,势必带来极大的性能损耗,故RocketMQ不支持任意进度的定时消息,而只支持特定延迟级别。
11.消息重试机制
消息重试是指消息在消费时,如果发送异常,消息中间件需要支持消息重新投递,RocketMQ支持消息重试机制。