1.消息队列
1.1.应用场景
- 异步处理 减少请求的等待时间,将请求放入队列待处理,提高总体性能
- 应用解耦 将消息存入队列,下游服务订阅并消费
- 流量削峰 在高峰期应对消息过多导致崩溃的情况,MQ积压请求,系统每次从MQ拉取能力范围内的数据
1.2.示例
- 电商系统
- 日志收集系统
- JMS
1.3.消息模型
-
队列模型:消费者之间是竞争关系,即每条消息只能被一个消费者消费
-
发布订阅模型:将消息发送至一个topic中,所有订阅该topic的服务消费(同时也是kafka的原理)
1.4.消费方式
- 同步 收到消息之前阻塞
- 异步 消息到达之后,自动调用onMessage方法
1.5.各种消息队列实现的比较
Kafka 1.1.0 | RabbitMQ 3.6.10 | RocketMQ 4.2.0 | |
---|---|---|---|
优先队列 | 不支持 | 支持,优先级0-10之间 | 支持,维护不同的优先级队列,根据message的优先级发送到对应的队列中 |
延迟队列 | 不支持 | 支持 | 支持 |
死信队列 | 不支持 | 支持 | 支持 |
重试队列 | 不支持 | 支持 | 支持 |
消费模式 | pull | pull+push | pull+长轮询 |
广播消费 | 支持,Kafka对于广播消息的支持更加正统 | 支持 | 支持 |
批量消息 | 支持,生产者异步发送 | 支持 | 支持,生产者同步发送 |
消息回溯 | 支持Kafka支持offset和timestamp两种维度进行消息回溯 | 不支持,一旦被确认消费就会被删除 | 支持 |
消息堆积 | 支持,海量消息堆积,堆积能力和磁盘大小挂钩 | 支持,但是内存达到阈值时,性能会受到影响 | 支持海量消息堆积 |
持久化方式 | 消息队列,segment方式 | 支持 | 消息队列 |
消息追踪 | 不支持。消息追踪可以通过外部系统来支持,但是支持粒度没有内置的细腻 | 支持 | 支持 |
消息过滤 | 客户端级别的支持,可用过kafka stream进行消息过滤 | 不支持,但是二次封装一下也比较简单 | 支持,可通过message tag、属性进行过滤 |
多租户 | 不支持 | 支持 | 不支持 |
多协议支持 | 只支持定义协议,目前几个主流版本间存在兼容性问题 | AMQS | JMS,OpenMessaging |
跨语言支持 | 当前版本Java编写,支持多种语言客户端 | 采用Erlang编写,支持多种语言客户端 | Java C++ Go |
流量控制 | 支持client和user级别,通过主动设置可将流控作用于生产者或消费者 | 流量控制基于credit-base算法,是内部被动触发的保护机制,用于生产者层面 | RocketMQ提供了针对不同维度的流量控制 |
消息顺序性 | 支持普通的顺序消息,即对于单个分区的消息发送和消费是有序的,但是不保证不重复 | 顺序性条件比较苛刻,需要单线程发送,单线程消费并且不采用延迟队列、优先级队列等一些高级功能,某种意义上来说不支持顺序性 | 支持普通的顺序消息和严格 |