MQ的好處
在微服務架構中,消息隊列帶來哪些好處呢
1. 改善寫操作請求的響應時間:生產者寫給隊列即可返回,無需等待下游服務響應,縮短鏈路調用時間
2. 更容易進行伸縮:小功能解偶爲獨立服務,更容易伸縮,提升處理能力
3. 削峯填谷:控制消費速度,降低系統訪問高峯壓力
4. 隔離失敗:消費者處理消息失敗,不會傳遞給生產者
5. 降低耦合:上下游服務解藕
6. 保證最終一致性
常見MQ的模式
點對點模式
多個消息生產者向消息隊列發送消息,多個消費者消費消息,每個消息只會被一個消費者消費
主題模式
多個消息消費者可以訂閱同一個主題,每個消費者都可以收到這個主題的消息拷貝,然後按照自己的業務邏輯分別進行處理計算
常見開源的MQ
- ActiveMQ:
Apache ActiveMQ® is the most popular open source, multi-protocol, Java-based message broker.
- RocketMQ:
Apache RocketMQ™ is a unified messaging engine, lightweight data processing platform.
- RabbitMQ:
RabbitMQ is lightweight and easy to deploy on premises and in the cloud. It supports multiple messaging protocols. RabbitMQ can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements.
- Kafka:
Apache Kafka is an open-source distributed event streaming platform used by thousands of companies for high-performance data pipelines, streaming analytics, data integration, and mission-critical applications.
網上常見的對比:
Kafka VS RabbitMQ
從不同使用場景對比下Kafka、 RabbitMQ
如何保證消息順序一致性
- RabbitMQ:多個消息,分發不同的QUEUE,導致順序錯亂。
- 需要保證順序的消息,發同一個Queue
- Kafka:生產者,發送同一個KEY,消費者開啓了多線程,導致順序錯亂
- 消費者加內存隊列,既能保證高併發,又可以保證消費順序
消息丟失
Kafka消息丟失
Kafka生產者丟失數據:leader接收到了消息,尚未同步給follower,leader宕機。
設置 acks=all,一定不會丟。
要求是, leader 接收到消息,所有的 follower 都同步到了消息之後,才認爲本次寫成功了。
如果沒成功,生產者會自動不斷的重試,重試無限次。容易導致重複消費。
Kafka自己丟失數據
設置四個參數
- 設置 replication.factor 參數:這個值必須大於 1,要求每個 partition 必須有至少 2 個副本
- min.insync.replicas 參數:這個值必須大於 1,這個是要求一個 leader 至少感知到有至少一個 follower 還跟自己保持聯繫
- 在 producer 端設置 acks=all:這個是要求每條數據,必須是寫入所有 replica 之後,才能認爲是寫成功了。
- 在 producer 端設置 retries=MAX:這個是要求一旦寫入失敗,就無限重試,卡在這裏了。
Kafka 消費者丟失數據:尚未消費消息就宕機
關閉自動offset,啓用手動offset
RabbitMQ消息丟失
RabbitMQ 生產者丟失數據
- 網絡丟包等故障。
- confirm模式,監聽失敗消息後無處理。
- 發送的路由沒有和queue綁定
- 事務機制:mq沒收到,異常報錯,回滾事務。性能消耗大,同步阻塞,吞吐量降低。
- AMQP協議提供的一個事務機制
- channel.txSelect()
- channel.txCommit()
- channel.txRollback()
- AMQP協議提供的一個事務機制
- RabbitTemplate Confirm確認機制&Return機制:callback回調處理
- RabbitTemplate:定義ConfirmCallback、ReturnCallback(消息無法路由到隊列,消息回退)
- 需要先設置rabbitTemplate.setMandatory(true)
- 分別對confirmCallback和returnCallback做回調處理
- 建立內存隊列,指定消息唯一ID,消息成功返回ack消息,失敗會回調定義大nack接口
RabbitMQ 自己丟失數據:消息未完全持久化,機器重啓
持久化設置
- durable=True:queue元數據持久化,
- deliveryMode爲2,將消息數據持久化
RabbitMQ 消費者丟失數據:尚未消費消息就宕機
關閉自動ack,啓用手動ack
消息重複(保證消息冪等性)
Kafka消息重複場景:消費完成,在準備提交offset時,還沒提交,消費者重啓
消息積壓
基本措施:
- 擴容。加個新topic,定義多個partion,消息轉發到新topic。增加消費者。
- 消費者性能優化:異步解藕,提升處理能力
消息消費模式
1.rabbitmq支持PUSH、PULL
- PUSH:及時性高,沒考慮消費者處理能力
- 默認PUSH
- PUSH限流
- 需要手動ack。channel.basicAck
- PULL:根據消費能力進行消費
- 需要消費者手動調用
- kafka只有PULL
高可用
Rabbit MQ:非分佈式MQ
- 單機模式
- 普通集羣模式
- 基本架構
- 優點:提升消費者吞吐量
- 缺點:1.集羣內部大量數據傳輸。2.沒啥可用性保障,queue所在節點宕機,會消息丟失。
- 基本架構
- 鏡像集羣模式
Kafka:分佈式,保證CA
- 基本架構
- 一個topic分爲多個partition,生產者可以指定數量。
- 一個partition可以有多個副本,最少兩個。replicat分leader,follower。
- 生產者會向leader發送消息,follower定期去pull,收到後發送ack給leader。可以指定寫多少replica,leader發送ack給生產者。
- acks=all,可以保證生產者不丟失數據,所有的follower都發送ack給leader,leader才發送ack給生產者,保證寫成功。
- leader維護有ISR(In Sync Replicas)列表,定時刷新。
參考
RabbitMQ is the most widely deployed open source message broker.
More than 80% of all Fortune 100 companies trust, and use Kafka.
Flexible & Powerful Open Source Multi-Protocol Messaging
Apache RocketMQ™ is a unified messaging engine, lightweight data processing platform.