1. rocketmq、rabbitmq、kafka的区别
- 架构设计和消息模型
特性 | rocketmq | rabbitmq | kafka |
---|---|---|---|
消息模型 | 基于主题和消费组,支持发布/订阅和点对点两种模型 | 基于队列模型,支持发布/订阅和点对点两种模型 | 基于分区的主题模型,主要用于日志流式处理和高吞吐量的发布/订阅 |
持久化 | 支持持久化,消息存储在磁盘上;有事务机制确保消息可靠性 | 支持消息持久化,主要依靠内存,使用磁盘持久化提高可靠性 | 默认持久化消息,依赖分区和日志的方式,保证高效持久化和高吞吐量 |
架构设计 | 分布式架构,内置高可用和分布式存储,支持分布式事务 | 集群模式可选,可以水平扩展但相对复杂,本质上是单节点的基础上扩展 | 本质上是分布式日志系统,天然支持分布式架构和高可用 |
- 性能和吞吐量
特性 | rocketmq | rabbitmq | kafka |
---|---|---|---|
吞吐量 | 吞吐量较高,但相比kafka略低,单机每秒处理十万级别消息 | 中等,适合低延迟,快速响应的小规模系统。单机吞吐量数千到几万 | 高吞吐量,适合大规模数据流处理,单机可以达到百万级别消息 |
延迟 | 延迟较低,但是并非最优。适合对实时性有一定要求的场景 | 延迟最低,适合实时性要求非常高的场景 | 延迟较低,但是相比rabbitMq稍高 |
- 消息可靠性和一致性
特性 | rocketmq | rabbitmq | kafka |
---|---|---|---|
消息可靠性 | 支持事务消息和严格的消息顺序,保证消息可靠送达 | 通过确认机制(ACK)、持久化和镜像队列确保消息的可靠性 | 通过分区副本机制和ACK机制保证消息的高可用和可靠性 |
一致性模型 | 支持分布式事务和严格顺序消费,可以保证消息的严格一致性 | 对于单个队列的顺序性支持较好,但不支持事务消息 | 强大的一致性和顺序性控制,通过分区和偏移量确保数据顺序 |
- 应用场景
特性 | rocketmq | rabbitmq | kafka |
---|---|---|---|
应用场景 | 金融支付、订单处理、分布式事务 | 微服务间的轻量级解耦、短消息处理、事件驱动和实时性要求较高的应用 | 大数据处理、日志聚合、流式处理、实时分析 |
- 扩展性和集群能力
特性 | rocketmq | rabbitmq | kafka |
---|---|---|---|
扩展性 | 支持水平扩展、但配置相对复杂、需要手动调整 | 通过集群模式实现扩展,单扩展复杂度高,高吞吐量时,可能需要更多节点 | 非常容易扩展,设计上支持高水平扩展 |
高可用性 | 通过主从架构和分布式机制保证数据安全 | 支持镜像队列和高可用配置,但实现复杂 | 通过分区副本机制实现高可用,能够自动进行分区重平衡和故障转移 |
总结
- rocketMQ: 适合对
分布式事务、消息顺序性
有着严格要求的场景,如金融支付、订单系统。其分布式架构和高可用性设计使其适合构建大规模分布式系统- RabbitMQ:适合需要
低延迟
和快速响应
的场景,比如事件驱动架构,微服务解耦
。由于其支持AMQP协议,使用起来灵活,适合中小型系统。- Kafka: 适合
高吞吐量和大数据处理
场景,如 日志收集、实时流数据分析、数据管道等。
2. 消息队列的模型有哪些
消息队列主要有两种模型:队列模型和发布/订阅模型
1. 队列模型
生产者往某个队列里面发送消息,一个队列可以存储多个生产者的消息,一个队列也可以有多个消费者,但是 消费者之间是竞争关系,即每个消息只能被一个消费者消费。
2. 发布/订阅模型
为了解决一条消息能被多个消费者消费的问题,发布/订阅模型就来了。该模型将消息发往一个topic即主题中,所有订阅了这个topic的订阅者都能消费这条消息。
RabbitMQ采用队列模型,RocketMQ和Kafka采用发布/订阅模型。
3. 如何保证消息不丢失
生产消息
生产者发送消息至Broker,需要处理Broker的响应,不论是同步还是异步发送消息,同步和异步回调都需要做好try-catch,妥善的处理响应,如果broker返回写入失败等错误消息,需要重试发送,当多次发送失败需要做日志记录
存储消息
存储消息阶段需要在消息刷盘后再给生产者响应,假设消息写入缓存中就返回响应,那么机器突然断电,消息就没了,而生产者以为已经发送成功了。
如果broker是集群部署,有多副本机制,即消息不仅仅要写入当前broker,还需要写入副本机中,那配置成至少写两台机子再给生产者响应。这样基本就能保证存储的可靠了。
消费消息
消费者真正执行完成逻辑之后,在发送给broker消费成功。
4. Kafka中关于事务消息的实现
Kafka的事务消息用在一次事务中需要发送多个消息的情况,保证多个消息之间的事务约束,即多条消息要么都发送成功,要么都发送失败。
5. Kafka中Zookeeper的作用
Zookeeper是一个开源的分布式协调服务框架,特别适合存储一些公共的配置信息、集群的一些元数据等。
他有持久节点和临时节点,临时节点配合watcher机制就非常有用。
当创建临时节点的客户端和zookeeper断连之后,这个临时节点就会消失,并且订阅了节点状态变更的客户端会收到这个节点状态变更的通知。
所以集群中某一个服务上线或者下线,都可以被检测到。因此,可以用来实现服务发现,也可以实现故障转移的监听机制。
Zookeeper为Kafka提供了元数据的管理,例如一些broker的信息、主题数据、分区数据等。
在每个broker启动的时候,都会和zookeeper进行交互,这样zookeeper就存储了集群中所有的主题、配置、副本等信息。
还有一些选举、扩容等机制也都依赖zookeeper。
例如控制器的选举:每个broker启动都会尝试在zookeeper注册/controller临时节点来竞选控制器,第一个创建/controller节点的broker会被指定为控制器。
竞争失败的节点也依赖watcher机制,监听这个节点,如果控制器宕机了,那么其他broker会继续来争抢,实现控制器的failover。
6. Kafka为什么要抛弃zookeeper
- Kafka身为中间件,依赖zookeeper中间件,这本身就很奇怪。
- 如果写入数据量过大,zookeeper的性能和稳定性就会下降,所以Kafka集群比较大,分区数很多的时候,zookeeper存储的元数据就会很多,性能也会变差。
- 另外,zookeeper也是分布式的,也需要选举,他的选举也不快,而在选举的时候是不提供服务的。
7. RabbitMQ中无法路由的消息会去哪里
在RabbitMQ中,如果消息无法路由到任何队列,其去向取决于交换机的配置和消息的属性设置。
RabbitMQ提供了两种处理无法路由消息的方法
- 如果配置了备用交换机,那么无法路由的消息会被发送到备用交换机
- 如果将消息的mandatory标志设为true,且消息无法路由到任何队列,RabbitMQ会将消息返回给发布者,发布者通过回调函数接受消息,反之,如果mandatory设为false则会直接将消息丢弃。
- 如果配置了死信队列,则可以被投递到死信队列中。
8. RabbitMQ中消息什么时候会进入死信交换机
- 消息被拒绝,且requeue参数为false
- 消息在队列中过期,且超时未被消费
- 队列达到最大长度
9. 如何保证消息的有序性
有序性分:全局有序和部分有序
。
全局有序
如果要保证消息的全局有序,首先只能由一个生产者往topic发送消息,并且一个topic内部只能有一个队列(分区)。消费者也必须是单线程消费这个队列,这样的消息就是全局有序的。
部分有序
绝大部份的有序需求都是部分有序,部分有序我们可以将topic内部划分为我们需要的队列数,把消息通过特定的策略发往固定的队列中,然后每个队列对应一个单线程处理的消费者。这样即完成了部分有序的需求,又可以通过队列数量的并发来提高消息处理效率。
10. 介绍AMQP协议
AMQP是一种开放标准的应用层协议,定义了消息的格式、消息队列的行为以及客户端和消息中间件之间的通信方式。
他的主要目标是为不同平台上的消息传递提供标准化的、高效和可靠的支持。
AMQP的基本组成部分
- Message Broker:消息中间件、负责接收、存储和转发消息,在AMQP中,RabbitMQ是一个典型的消息代理实现。
- Exchange:交换机、负责接收消息并根据绑定规则将消息路由到消息队列。AMQP定义了多种交换机类型,如direct、fanout、topic、header。
- Queue:队列,用于存储消息,消费者可以从队列中接受消息。
- Binding:绑定,定义交换机和队列之间的关系和消息路由规则
- Message:消息,是在系统中传输的基本数据单元,包含消息头和消息体。
AMQP的主要特性
- 消息路由:AMQP支持复杂的消息路由机制,通过交换机和绑定可以实现灵活的消息传递路径。
- 消息可靠性:通过消息确认、持久化、死信队列等机制保证消息的可靠性和持久性。
- 消息传递保证:提供至少一次、至多一次和正好一次三种传递保证。
- 消息顺序:确保消息在队列中的顺序传递。