为什么要使用MQ?
优点:
- 解耦:降低分布式系统不用应用之间的代码耦合
- 异步:收到消息,扔到MQ上
- 削峰:对于突然到来的大量请求,可以以稳定的速度逐步处理,避免系统负载过高
缺点: - 提高了系统的复杂度
- 降低了可用性
- 一致性问题
几种MQ的对比
| 特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
|---|---|---|---|---|
| 单机吞吐量 | 万级 | 万级 | 十万级 | 十万级 |
| topic数量 | - | - | 在topic数量从几百到几千级别时,吞吐量较小幅度下降(优势) | 在topic从几百到几千级别时,吞吐量下降幅度较大 |
| 时效性 | ms | us(优势) | ms | ms |
| 可用性 | 高,主从架构 | 高,主从架构 | 非常高,分布式架构 | 非常高,分布式架构 |
| 消息可靠性 | 较低 | 较低 | 通过参数化配置可实现0丢失 | 通过参数化配置可实现0丢失 |
| 功能支持 | 完备 | 基于erlang开发,并发能力很强 | 完备 | 功能较为简单,不支持消费重试,不支持消费回溯,不支持消息查询 |
RockMQ消息发送的方式
- 同步(sync):发送者向MQ执行发送消息的API时,同步等待,直到消息服务器返回发送结果
- 异步(async):发送者向MQ执行发送消息API时,指定消息发送成功后的回调函数,然后调用消息发送API后,记录返回,消息发送成功或者失败的回调任务在一个新的线程中执行
- 单向(oneway):消息发送者向MQ执行发送消息API时,直接返回,不等待消息服务器的结果,不在乎消息是否成功存储在消息服务器上
RocketMQ如何实现消息0丢失
从三方面保证
- Producer生产
生产者发送消息给broker,broker收到后返回确认消息给生产者,代表消息生成阶段没有丢失。 - Broker存储
- 消息到了broker,将会优先保存到内存中,然后立即返回确认给生产者,然后定期批量将消息从内存异步刷入磁盘,这种方式不能保证消息不丢失,因为如果出现机器掉电,异常宕机,消息还没有来得及从内存刷入磁盘,就会发生消息丢失,若想保证消息一定不丢失,需要将消息的保存机制变为同步刷盘的方式,即消息存储磁盘成功,再返回响应;
- 在集群环境中,为了保证消息不丢失,消息还需要复制给slave节点,这种情况需要设置同步复制的方式,复制完成再返回确认
- Consumer消费
消费者在消费成功后,返回给broker CONSUME_SUCCESS状态,如果broker未收到消费者的确认,消费者下次还会再次拉取到该消息,这样可以保证消息在消费过程中出现异常或者在网络传输中丢失后,还可以再次消费消息,同时消费者需要保证幂等
消费者的消费模式
- 集群消费
一个 ConsumerGroup中的各个 Consumer 实例分摊去消费消息,即一条消息只会投递到一个ConsumerGroup下面的一个实例。 - 广播消费
消息将对一 个Consumer Group 下的各个 Consumer 实例都投递一遍。即使这些 Consumer 属于同一个Consumer Group,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。