文章目录
概述
阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改为RocketMQ,是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下mq的架构,目前主要多用于订单交易系统。
RocketMQ 是一款分布式、队列模型的消息中间件,Apache Alibaba RocketMQ 是一个消息中间件。消息中间件中有两个角色:消息生产者和消息消费者。RocketMQ 里同样有这两个概念,消息生产者负责创建消息并发送到 RocketMQ 服务器,RocketMQ 服务器会将消息持久化到磁盘,消息消费者从 RocketMQ 服务器拉取消息并提交给应用消费。
官方提供了一些不同于kafka的对比差异:
https://rocketmq.apache.org/docs/motivation/
RocketMQ 是阿里巴巴的分布式消息中间件,在 2012 年开源,在 2017 年成为 Apache 顶级项目。
电商项目 rocketmq 能,消息可靠性能保证,幂等业务自己保证
消息队列作为高并发系统的核心组件之一,能够帮助业务系统解构提升开发效率和系统稳定性。
RocketMQ 特点
支持严格的消息顺序
支持 Topic 与 Queue 两种模式
亿级消息堆积能力
比较友好的分布式特性
同时支持 Push 与 Pull 方式消费消息
历经多次天猫双十一海量消息考验
● 能够保证严格的消息顺序
● 提供针对消息的过滤功能
● 提供丰富的消息拉取模式
● 高效的订阅者水平扩展能力
● 实时的消息订阅机制
● 亿级消息堆积能力
RocketMQ 优势
目前主流的 MQ 主要是 RocketMQ、kafka、RabbitMQ,其主要优势有:
支持事务型消息(消息发送和 DB 操作保持两方的最终一致性,RabbitMQ 和 Kafka 不支持)
支持结合 RocketMQ 的多个系统之间数据最终一致性(多方事务,二方事务是前提)
支持 18 个级别的延迟消息(RabbitMQ 和 Kafka 不支持)
支持指定次数和时间间隔的失败消息重发(Kafka 不支持,RabbitMQ 需要手动确认)
支持 Consumer 端 Tag 过滤,减少不必要的网络传输(RabbitMQ 和 Kafka 不支持)
支持重复消费(RabbitMQ 不支持,Kafka 支持)
Kafka的事务并不是完全意义上的分布式事务,主要为解决消费发送过程中多分区多会话情景下的幂等性而生
削峰填谷: 主要解决瞬时写压力大于应用服务能力导致消息丢失、系统奔溃等问题
系统解耦: 解决不同重要程度、不同能力级别系统之间依赖导致一死全死
提升性能: 当存在一对多调用时,可以发一条消息给消息系统,让消息系统通知相关系统
蓄流压测: 线上有些链路不好压测,可以通过堆积一定量消息再放开来压测
RocketMq特点
3、亿级消息的堆积能力,单个队列中的百万级消息的累积容量。
4、高可用性:Broker服务器支持多Master多Slave的同步双写以及Master多Slave的异步复制模 式,其中同步双写可保证消息不丢失。
5、高可靠性:生产者将消息发送到Broker端有三种方式,同步、异步和单向,其中同步和异步都 可以保证消息成功的成功发送。Broker在对于消息刷盘有两种策略:同步刷盘和异步刷盘,其中 同步刷盘可以保证消息成功的存储到磁盘中。消费者的消费模式也有集群消费和广播消费两种,默 认集群消费,如果集群模式中消费者挂了,一个组里的其他消费者会接替其消费。综上所述,是高可靠的。
6、支持分布式事务消息:这里是采用半消息确认和消息回查机制来保证分布式事务消息的,
7、支持消息过滤:建议采用消费者业务端的tag过滤
8、支持顺序消息:消息在Broker中是采用队列的FIFO模式存储的,也就是发送是顺序的,只要保 证消费的顺序性即可。
9、支持定时消息和延迟消息:Broker中由定时消息的机制,消息发送到Broker中,不会立即被 Consumer消费,会等到一定的时间才被消费。延迟消息也是一样,延迟一定时间之后才会被Consumer消费。
RocketMQ怎么保障高性能又不丢数据
RocketMQ 是一个高性能、高可靠的分布式消息中间件,广泛应用于大规模分布式系统中。为了保障高性能和数据不丢失,RocketMQ 采用了多种技术和机制。以下是 RocketMQ 如何保障高性能和数据不丢失的详细介绍:
RocketMQ 通过异步刷盘、批量消息、零拷贝、多线程处理和顺序写入等技术保障了高性能。同时,通过同步刷盘、主从复制、ACK机制、事务消息、重试机制和定期刷盘与检查点等机制,RocketMQ 能够有效地保障数据不丢失。这些技术和机制结合,使得 RocketMQ 成为一个高性能且高可靠的分布式消息中间件,适用于大规模分布式系统的消息传输和处理。
高性能保障
异步刷盘:
RocketMQ 支持异步刷盘机制,消息写入内存后立即返回,后续再将内存中的数据异步写入磁盘。异步刷盘大大提升了消息写入的性能。
批量消息:
RocketMQ 支持批量消息发送和批量消息消费。批量处理可以减少网络 IO 次数,提高吞吐量。
零拷贝:
RocketMQ 使用了操作系统的零拷贝技术(如 Java NIO 的 FileChannel.transferTo 方法),减少了数据在内核态和用户态之间的拷贝次数,提高了消息传输的效率。
多线程处理:
RocketMQ 内部使用多线程和多队列并发处理消息。通过合理的线程池配置和队列设计,实现了高效的消息读写和传输。
顺序写入:
RocketMQ 的消息存储采用了顺序写入磁盘的方式,顺序写入相比随机写入性能更高,能更好地利用磁盘的顺序写能力。
数据不丢失保障
同步刷盘:
RocketMQ 提供同步刷盘机制,可以配置为必须将消息写入磁盘后才返回确认给生产者。虽然同步刷盘会降低一些性能,但能保证数据的持久化,不会丢失。
主从复制:
RocketMQ 支持主从架构,主节点和从节点之间进行数据同步。即使主节点发生故障,从节点也能接管,确保数据不丢失。
ACK机制:
RocketMQ 在消息消费时使用 ACK 确认机制。消费者必须显式确认消息处理成功后,才会从队列中删除消息,确保消息被成功处理。
事务消息:
RocketMQ 支持事务消息,允许生产者发送半消息,然后执行本地事务,根据本地事务的结果提交或回滚消息。事务消息机制确保了消息和业务操作的一致性。
重试机制:
RocketMQ 内置重试机制,消息发送失败后会自动重试多次,直到成功或达到最大重试次数。对于消费端,也有消费失败重试机制,确保消息最终被成功处理。
定期刷盘和检查点:
RocketMQ 会定期将内存中的消息数据刷盘,并保存检查点。即使在异常情况下,RocketMQ 也能通过检查点和日志恢复数据。
rocketmq发送消息的三种方式
在实际使用场景中,利用何种发送方式,可以总结如下:
● 当发送的消息不重要时,采用one-way方式,以提高吞吐量;
● 当发送的消息很重要是,且对响应时间不敏感的时候采用sync方式;
● 当发送的消息很重要,且对响应时间非常敏感的时候采用async方式;
RocketMQ为什么要放弃Zookeeper
所以,只要是跟分布式服务调用的场景,都需要一个注册中心,在RocketMQ当然也中需要有个这样的角色来管理Broker的信息。而Kafka就是用了现成的Zookeeper,但是RocketMQ却偏偏没有这么做,而是自己实现了一个服务,这个服务叫做NameServer。
我们可以把NameServer理解为是RocketMQ的路由中心,每一个NameServer节点都保存了全量的路由信息。为了保证高可用,NameServer自身也可以做集群的部署。它的作用有点像Eureka或者Redis的Sentinel。
也就是说,Broker会在NameServer上注册自己,Porducer和Consumer用NameServer来发现Broker。
每个Broker节点在启动时,都会根据配置遍历NameServer列表。与每个NameServer建立TCP长连接,注册自己的信息,之后每隔30s发送心跳信息。如果Broker挂掉了,不发送心跳了,NameServer怎么发现呢?
所以,除了主从注册,还有定时探活。每个NameServer每隔10s检查一下各个Broker的最近一次心跳时间,如果发现某个Broker超过120s都没发送心跳,就认为这个Broker已经挂掉了,会将其从路由信息里移除。
既然,Nameserver的作用也是用来管理Broker的服务的,也就是服务注册与发现,那为什么不直接用Zookeeper、Consul、etcd、Eureka这样的组件呢?
实际上在RocketMQ的早期版本中,跟Kafka一样也是用Zookeeper实现服务管理的,但到RokcetMQ开源的时候去掉了ZooKeeper依赖,转而采用自己的NameServer。
因为,RocketMQ是一个保持最终一致性的架构设计,它架构决定了它只需要一个轻量级的元数据服务器就足够了,而不需要像Zookeeper这样的强一致性解决方案。不依赖另一个中间件,从而减少整体维护成本。
根据著名的CAP理论,在一致性(Consistency)、可用性(Availability)、分区容错性(PartitonTolerance)中,Zookeeper实现了CP,而NameServer选择了AP,放弃了实时一致性。
RocketMQ怎么保证集群高可用性
要确保 RocketMQ 集群的高可用性,可以采取以下几个措施:
- 部署多个 NameServer 节点: NameServer 是 RocketMQ 集群的管理节点,负责管理路由信息等。部署多个 NameServer 节点可以提高系统的可用性,当某个节点发生故障时,其他节点可以继续提供服务。
- 部署多个 Broker 节点: Broker 负责存储消息数据和处理消息的发送和接收。通过部署多个 Broker 节点,可以实现消息的水平扩展和负载均衡,提高系统的吞吐量和可用性。
- 配置主从同步: 在每个 Broker 节点上,可以配置主从同步机制,确保消息数据的备份和容灾。当主节点出现故障时,从节点可以顶替其角色继续提供服务。
- 使用消息复制机制: 在 RocketMQ 中,可以配置消息的同步复制或异步复制机制,确保消息数据的可靠性和一致性。通过适当配置复制机制,可以提高系统的可靠性和容错能力。
- 监控和报警: 建立完善的监控和报警系统,定期检查集群的状态和性能指标,及时发现并处理潜在的问题,确保系统的稳定运行。
- 定期备份数据: 定期备份消息数据和重要配置信息,以防止数据丢失或损坏。合理设置备份策略,确保数据的安全性和可恢复性。
通过以上措施的综合应用,可以有效提升 RocketMQ 集群的高可用性,保障系统的稳定运行和消息服务的可靠性。
RocketMQ如何保证全链路消息零丢失
要保证 RocketMQ 全链路消息零丢失,可以采取以下几个措施:
- 持久化消息存储: RocketMQ 提供了消息的持久化存储机制,可以将消息持久化到磁盘上,确保即使在发生故障或重启时,消息数据也不会丢失。
- 同步复制机制: 配置 RocketMQ Broker 节点之间的同步复制机制,确保消息数据在主从节点之间的同步和备份。这样可以提高消息的可靠性和容错能力,避免消息在传输过程中丢失。
- 消息确认机制: 在生产者发送消息时,可以配置消息确认机制,确保消息成功发送到 Broker 后再返回确认结果。消费者消费消息时,也可以配置消息确认机制,确保消息被成功消费后再返回确认结果。
- 事务消息机制: 对于需要保证消息的一致性和可靠性的业务场景,可以使用 RocketMQ 提供的事务消息机制。通过事务消息,可以在本地事务执行成功后再发送消息,确保消息不会丢失。
- 监控和报警: 建立完善的监控系统,监控消息的发送、接收和处理过程,及时发现潜在问题并进行处理。设置报警机制,及时通知相关人员处理异常情况。
- 数据备份与恢复: 定期备份消息数据和重要配置信息,以防止数据丢失或损坏。合理设置备份策略,并测试数据恢复的流程,确保在发生灾难时能够快速恢复数据。
- 高可用性部署: 部署多个 Broker 节点和 NameServer 节点,配置主从同步机制,确保系统的高可用性。避免单点故障,提供全链路的消息服务。
RocketMQ如何解决消息幂等性问题
RocketMQ 本身并没有提供消息幂等性的解决方案,但可以通过在业务系统中进行设计和实现来解决消息幂等性问题。以下是一些常见的在 RocketMQ 中解决消息幂等性问题的方法:
- 唯一消息标识:在消息的业务数据中添加一个唯一标识符,例如订单号、交易号等,作为消息的唯一标识。
- 消息去重表:业务系统可以维护一个消息去重表,记录已经处理过的消息唯一标识,当接收到重复消息时,先查询消息去重表来判断是否已经处理过该消息。
- 幂等性接口设计:在业务系统中设计具有幂等性特性的接口,确保同一消息多次调用该接口的效果与调用一次相同。
- 乐观锁控制:在处理消息时使用数据库乐观锁或分布式锁来确保同一消息不会被多次处理。
- 版本号校验:对于需要更新的数据,可以使用版本号来进行校验,确保同一消息多次更新时只有第一次有效。
- 消息消费状态标记:在业务系统中对已处理的消息进行状态标记,确保同一消息已经处理过后不会再次处理。
RocketMQ的事务消息机制有什么用
RocketMQ 的事务消息机制用于解决分布式事务中的消息一致性问题,确保消息的可靠传递和处理。事务消息是指在发送消息时,先将消息发送到消息服务器,但消息并不立即被消费,而是经过一系列预处理后再决定是否提交或回滚消息。
事务消息机制通常适用于涉及多个操作或服务间的复杂业务场景,以确保多个操作的一致性和可靠性。以下是 RocketMQ 事务消息机制的一些用处:
- 分布式事务的一致性:在分布式事务场景下,可能涉及多个操作或服务,通过事务消息机制可以确保各个操作的执行状态一致,避免数据不一致性问题。
- 可靠的消息处理:事务消息机制可以保证消息的可靠传递和处理,避免消息丢失或重复消费的情况发生。
- 消息的顺序性:通过事务消息机制,可以保证消息的处理顺序性,确保消息按照正确的顺序进行处理,避免乱序导致的问题。
- 消息的幂等性:通过事务消息的事务处理机制,可以保证消息的幂等性,即同一条消息重复发送时,最终处理的结果保持一致。
- 补偿机制:在事务消息机制中,还可以实现消息的补偿机制,当某个操作失败时,可以通过回滚事务或重新执行事务来保证消息的处理完整性。
总的来说,RocketMQ 的事务消息机制可以帮助解决分布式系统中的消息一致性和可靠性问题,保证复杂业务场景下的消息处理正确性,提高系统的稳定性和可靠性。
RocketMQ如何提升客户端负载均衡性
RocketMQ 提升客户端负载均衡性的方法主要包括以下几点:
- 使用负载均衡算法:RocketMQ 客户端可以通过选择合适的负载均衡算法来实现负载均衡。例如,基于权重的负载均衡算法、随机选择算法、轮询算法等。根据业务需求和场景选择适合的负载均衡算法可以有效平衡消息消费者之间的负载。
- 动态调整负载均衡策略:RocketMQ 提供了动态调整负载均衡策略的能力,可以根据实时的负载情况和消费者状态动态调整负载均衡策略,使得消息能够更加均匀地分配给各个消费者。
- 消费者组合理配置:在 RocketMQ 中,可以通过合理配置消费者组,将消费者分配到不同的消费者组中,避免单个消费者组负载过重。合理的消费者组配置可以提高消息消费的并发度和负载均衡性。
- 水平扩展消费者:当单个消费者无法满足需求时,可以通过水平扩展消费者实例的方式来提升客户端负载均衡性。增加消费者实例数量可以分担消息消费的压力,提高系统的整体吞吐量和负载均衡性。
- 监控和调优:定期监控 RocketMQ 系统的消费者状态和消费情况,及时发现负载较高或消费者异常的情况,并进行相应的调优和优化。通过监控系统性能指标、消费者状态等信息,可以及时调整负载均衡策略,保持系统的稳定性和负载均衡性。
通过以上方法,可以有效提升 RocketMQ 客户端的负载均衡性,确保消息消费的高效性和稳定性,提高系统整体的性能表现。
RocketMQ如何实现定时延迟消息
RocketMQ 实现定时延迟消息的方式是通过消息的延迟级别(Delay Level)来实现。具体而言,RocketMQ 的消息生产者可以设置消息的延迟级别,消息服务器会根据这个级别将消息存储在不同的延迟队列中,然后在指定的时间后再将消息投递给消费者进行消费。
实现步骤如下:
- 设置延迟级别:消息生产者在发送消息时,可以通过设置消息的延迟级别来指定消息的延迟时间。RocketMQ 支持多个预定义的延迟级别,如 1s、5s、10s 等,开发者可以根据实际需求选择合适的延迟级别。
- 存储到延迟队列:消息服务器会根据消息的延迟级别将消息存储到对应的延迟队列中,而不是立即投递给消费者。
- 定时投递:当消息达到设定的延迟时间后,RocketMQ 会将消息从延迟队列中取出,并投递给对应的消费者进行消费。
通过以上方式,RocketMQ 实现了定时延迟消息的功能,开发者可以方便地使用延迟级别来控制消息的投递时间,满足各种业务场景下的延迟消息需求,比如订单超时提醒、定时任务等。
要在 Java 代码中实现 RocketMQ 的定时延迟消息,您可以按照以下步骤进行操作:
1. 首先,确保您已经正确配置了 RocketMQ 的依赖项和相关配置文件。
2. 创建一个 RocketMQ 生产者实例,并设置为支持延迟消息的模式。例如:
DefaultMQProducer producer = new DefaultMQProducer("your_producer_group");
// 设置为支持延迟消息的模式
producer.setDelayTimeLevel(3); // 设置延迟级别,这里使用预定义的级别3
producer.start();
3. 构建并发送带有延迟属性的消息。例如:
Message message = new Message("your_topic", "your_tags", "your_body".getBytes());
// 设置消息的延迟级别,这里使用预定义的级别3
message.setDelayTimeLevel(3);
SendResult result = producer.send(message);
System.out.println("消息发送结果:" + result.getSendStatus());
4. 创建一个 RocketMQ 消费者实例,并注册消息监听器来处理延迟消息。例如:
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("your_consumer_group");
consumer.subscribe("your_topic", "*");
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> messages, ConsumeConcurrentlyContext context) {
for (MessageExt message : messages) {
// 处理接收到的延迟消息
System.out.println("接收到延迟消息:" + new String(message.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
通过上述代码,您可以在 RocketMQ 中实现定时延迟消息的功能。您可以根据具体需求自定义延迟级别,并在消费者端处理接收到的延迟消息。请注意,延迟消息需要使用推模式(Push Consumer)来接收,因为拉模式(Pull Consumer)不支持延迟消息的消费。
RocketMQ如何保证高效文件存储
RocketMQ 通过 CommitLog 来实现高效的文件存储。CommitLog 是 RocketMQ 存储消息的核心机制,它将消息持久化到磁盘中。以下是 RocketMQ 如何保证高效文件存储的一些关键点:
- 顺序写入:RocketMQ 的 CommitLog 采用追加写入方式,即消息是按顺序写入到 CommitLog 文件中的,而不是随机写入。这种顺序写入的方式有利于提高磁盘 IO 的效率,减少磁盘的寻道时间,提升写入性能。
- 内存映射:RocketMQ 在 CommitLog 的实现中使用了内存映射(Memory Mapped File)的技术。内存映射可以将文件直接映射到内存中,避免了数据在用户空间和内核空间之间的复制,提高了 IO 性能。
- 批量刷盘:RocketMQ 采用批量刷盘(Batch Flush)的方式来减少磁盘 IO 次数,提高性能。即将多个消息一起刷写到磁盘而不是每条消息单独刷写,减少了磁盘 IO 的开销。
- 零拷贝:RocketMQ 在消息存储过程中尽可能地使用零拷贝技术,减少数据在内存和磁盘之间的复制次数,提高了数据传输的效率。
- 异步刷盘:RocketMQ 使用异步刷盘机制来提高性能。消息首先被写入内存缓冲区,然后通过异步线程定期将内存缓冲区中的消息批量刷写到磁盘中,避免了同步写入导致的性能损失。
通过以上优化策略,RocketMQ 在文件存储方面能够实现高效的性能表现,提供稳定可靠的消息存储服务,并且保证了高吞吐量和低延迟的消息处理能力。
RocketMQ如何设计文件刷盘机制
RocketMQ 是一个分布式消息中间件,文件刷盘机制是指将内存中的数据定期或在特定条件下写入磁盘,以保证数据的持久性和安全性。在 RocketMQ 中,文件刷盘机制主要涉及到 CommitLog 文件的刷盘。
下面是 RocketMQ 中 CommitLog 文件刷盘机制的设计原理:
- 同步刷盘:RocketMQ 采用同步刷盘方式,即消息发送完成后,会立即将消息写入内存映射的 CommitLog 文件,并通过调用 fsync 系统调用将数据强制刷写到磁盘,确保数据持久化。
- 刷盘策略:RocketMQ 提供了两种刷盘策略,分别是SYNC_FLUSH 和 ASYNC_FLUSH。SYNC_FLUSH 表示同步刷盘,即每条消息发送后都会执行一次 fsync 操作;ASYNC_FLUSH 表示异步刷盘,即消息先写入内存,然后由专门的线程定期将数据刷写到磁盘。
- 定时刷盘:RocketMQ 中的 CommitLog 文件会定时进行刷盘操作,以确保数据的持久化。定时刷盘可以通过配置参数 commitInterval 来设置刷盘的时间间隔。
- 刷盘条件:除了定时刷盘外,RocketMQ 还会根据消息的存储情况、内存使用率等条件来触发刷盘操作,确保数据及时写入磁盘。
通过以上设计,RocketMQ 实现了可靠的文件刷盘机制,保证了消息数据的持久化和安全性。