- AMQP協議
1.協議模型
1.協議連接步驟
1.1.生產者與服務建立連接----》連接host ----》exchange
1.2.Connection :建立連接
1.3.Channel:網絡信道,是進行消息的讀寫的通道,客戶端可建立多個channel,每個channel代表一個任務。
1.4.Message:由properties 和body組成。Properties可以對消息進行設置:是否延遲,發送時 機
1.5.Virtual host: 虛擬地址。進行邏輯隔離,是最上層的消息路由,比如說mq服務可能要關聯多個業務服務,每個業務服務會需要對應一個獨立的區域。一個virtual host 可以有多個exchange和queue。但同一個virtual host裏面的exchange和queue的名稱不能相同。
1.6.Exchange:路由。生產者把消息發送到路由器上
1.7.Bingding:exchange和Queue之間的虛擬連接,bingding可以包含routing key。
-
- Routing key:路由規則,虛擬機用其確認如何路由一個指定的消息,
- Queue:消息隊列。
2. 交換機exchange
2.1 架構圖
2.2.基本屬性
2.2.1.type: direct , topic , fanout , headers ,( sharding 需要安裝插件 )
2.2.2.Durability:是否需要持久化,true爲需要
2.2.3.Auto Delete :
當最後一個綁定到Ecchange上的隊列刪除後,自動刪除該exchange,即沒有隊列關聯路由了
2.2.4.Internal:
當前exchange 是否用於MQ內部使用,默認爲false。
Argurments
2.3 Direct 路由
即:所有發送到Direct Echange的消息被轉發到RouteKey中指定的Queue
Direct模式可以使用RabbiMq自帶的Exchange:default Exchange ,所以不需要將Exchange 進行任何綁定操作,消息傳遞時RouteKey 必須完全匹配纔會被隊列接收,否則消息被拋棄。
2.4. Topic
即:所有發送到Topic exchange的消息被轉發到所有關係RouteKey中指定Topic的Queue上
Exchange將RouteKey和某個Topic進行模糊匹配
此時隊列需要綁定一個topic
三.消息投遞及確認
3.1 消息投遞的保證
3.1.1. 生產端的可靠性投遞
解析:生產端要把要發送的消息持久化而不是直接發送。
B.confirm Listener :接收消費端的消息是否被消費成功。True就是成功了
如果step3 由於網絡抖動,消費端沒有把成功消費的消息告知生產者。
則
C.Retry send :生產端可以設置一個消息超時時間,如果超時後會重新發送
即保證消息成功發出,且發送端收到MQ接口broker確認應答
還有消息的補償機制
C.收到消息的持久化
D.消息的延遲投遞,做二次確認,回調檢查
3.1.2 可靠性投遞三
在高併發場景下的消息投遞
即消息的延遲投遞,做二次確認,回調檢查
主要是減少數據庫操作,
解析:stop1:生產消息
Step2 :若干時間後訂閱消息被消費的確認通知,該通知由回調服務發送
Step4:如果消息被正常消息則向mq發送消息服務通知回調服務
Step5:監聽消息被正常消費後持久化數據
Step6:如果消息消費失敗,則發起補償通知給消息的生產者
- Upstream service: 生產端,上游服務
第一步把發送的消息先入庫
DownStream service :消費端
C.CallBack service :回調服務
D.MQ Broker:
備註:在整個業務鏈條中沒有任何分佈式事務
3.1.3 . 消息的冪等性
3.1.3.1. 消費端保證消息的冪等性
即數據庫的樂觀鎖
A.在海量訂單的業務高峯期,如何避免消息重複消費?
即:消費端實現消息的冪等性
- 主流方案:(1)唯一ID+指紋碼機制,利用數據庫主鍵去重
Select count( 1 ) from table where id = 唯一ID+指紋碼機制(業務規則)
好處:實現簡單
缺點:高併發下對數據庫的寫入的性能瓶頸
解決方案:ID進行分庫分表進行算法路由。
(2)利用redis原子性去重
3.2 消息的ACK和重回隊列
可靠性投遞
3.2.1 確認機制實現
A.第一步,在channel上開啓確認模式:channel。confirmSelect();
B. 第二步,在channel上添加監聽,addConfirmListener,監聽成功和識別的返回結果,根據具體的結果對消息進行重新發送或記錄日誌後續處理
3.2.2 return 消息機制
A.return Listener 用於處理一些不可路由消息:即發送的消息當前的exchange不存在或者路由的key路由不到。這個時候就要監聽這種不可達的消息,使用Return Listener
3.2.3.生產者發送消息後怎麼樣確認mq服務器是否收到消息
兩各方式:
- AmQP 實現了事務機制
事務機制
- Txselect
用戶將當期channel設置成transation模式,trCommit用於提交事務,如果有異常則txRollback回滾
- 消息可靠性投遞confirm 模式
生產者端confirm模式的實現原理:
3.3 消息限流
3.3.1 消費端的限流
Eg:RabbitMq 服務器有數萬條消息,當
RabbitMq提供了一種qos(服務質量保證)功能,
3.3 消費端ACK與重回隊列
3.3.1 手工ACK和NACK
A.消費端未消費成功,程序本身的異常,業務異常,可以進行消息補償
B.演技
3.3.2. 消費端的重回隊列
A.對於沒有成功消費的消息重新給broker
3.3.3. API 使用說明
3.4 TTL消息
解釋:RabbitMq 支持消息的過期時間,當消息發送時可以指定消息生存時間
RabbitMq也支持隊列的過期時間,從消息的入隊列開始計算,只要超過了隊列的超時時間,則消息會自動清除。
3.4.1
3.5 死信隊列—DLX
3.5.1 當消息在隊列中變成死信,
3.5.2 消息變成死信的途徑
A.消息被拒絕 且request=false
B.消息TTL過期
C.隊列長度最大
四.RabbitMq 使用
- 使用方式種類:
- 單發送多接受
- 發佈訂閱模式
2. 怎樣保證消息的穩定性
2.1. publisher confirms :發佈方確認
2.2. message 持久化
2.3 acknowlegement :Consumer 確認
3.怎樣避免消息丟失
3.1 將Queue 和message 都設置爲可持久化,還有就是使用事務,
- RabbitMq 持久化的特點
- 如果要在重啓後保持消息的持久化必須設置消息是持久化的標識
4.消息的廣播類型
4.1.fanout廣播模式
4.2.direct 廣播模式
4.3 topic 廣播模式
5. 怎樣實現延遲消息隊列??
5.1 延遲任務通過消息的TTL 和 Dead letter exchange來實現。
我們需要建立2個隊列,一個用於發送消息,一個用於消息過期後的轉發目標隊列
6.RabbitMq 集羣作用
6.1 集羣裏面可以共享user,vhost ,queue,exchange ,
所有的數據和狀態都是必須在所有節點上覆制的。一個例外是
7.rabbitMq的節點類型
7.1 內存節點
7.2 磁盤節點
五.RabbitMq 集羣架構
1. 主備架構模式
主節點可以提供讀寫,但從節點不做任何事情,只在主節點宕機時,從節點替代主節點服務。這個主從的模式是有本質區別的。這個架構在併發量低的業務可以使用
這個模式activemq 利用zk 做主備一樣。
1.1 主備架構設計
- Haproxy:是一個tcp基別的代理,
其配置如下:
Bind 0.0.0.0:5672 #配置tcp模式
Mode tcp #簡單的輪詢
Balance roundrobin #主節點
Server bhz76 IP :5672 check inter 5000 rise 2 fall 2
Server bhz77 IP:5672 backup check inter 5000 rise 2 fall 2 #備用節點
說明:集羣節點配置#inter每個5秒對mq集羣做健康檢查,2次正確證明服務器可用,3次失敗證明服務器不可用
2.遠程模式架構
2.1 說明:遠程模式可以實現雙活的一種模式,簡稱shovel模式,
即把消息進行不同數據中心的複製,可以跨地域讓多個mq集羣互聯
3.鏡像模式架構Mirror
3.1 Mirror鏡像隊列,
爲了保證rabbitm數據的高可用解決方案,主要是實現數據的同步,一般是
3個節點,該模式可保證數據完全不丟失。
3.2.架構圖
-
-
- keepAlived:
-
4.多活模式
4.1 是實現異地數據複製的主流模式,
因爲shovel模式配置複雜。這個模式依賴插件:federation插件,可實現AMQP的數據通信
4.2. 架構圖
Federation exchange:不需要構建cluster,在brokers之間傳輸消息。連接的雙方可使用不同的users和virtual hosts 。雙方也可以
六.鏡像集羣搭建
1.服務組件
2.keepAlived
主要是通過VRRP(虛擬路由器冗餘協議)協議實現高可用功能,
- 三個作用:
- 管理LVS軟件
- 實現LVS集羣的監控檢測
- 集羣配置
- hipe_compile: erlang compiler編譯小提示性能
- vm_memory_high_watermark:內存低水位線,若地域該水位線,則
七.RabbitMq 設計架構整體方案
1.實現思路
2.架構完成功能:
- 支持消息高序列化的轉化和異步發送
- 支持消費和生產的實例的連接池化緩存化,
- 支持可靠性投遞,保障消息不能丟失
- 支持消費端的冪等性操作,避免消費端重複消費
- 支持快速消息發送,在日誌收集,統計分析等需求下保證高吞吐量
- 支持延遲消息模式,消息可以延遲發送,指定延遲時間,用於延遲檢查,服務限流場景
- 支持事務消息,保障100%可靠性投遞,
- 支持順序消息,保障消息送達消費端的前後順序,例如下訂單等複合操作
- 支持消息補償,重試,快速定位異常,失敗消息
- 支持消息集羣負載均衡,保障消息落到具體set集羣
- 支持消息路由策略
3.生產端組件說明
3.1.RabbitTemplateContainer : RabbitTemplate複用池,高併發下可以重複利用
-
- RabbitTemplateConfirmCallback
4. 消費端組件
4.1.AsycnMessageInter:
4.2. IdempotenRabbitHandler:消費者冪等性保障攔截器
5.架構模式說明
5.1迅速發送消息模式
6. 事務消息
Eg:單筆大額現金交易,希望這個消息優先級最高,且可靠性要求100%。和銀行系統都要兼顧,所以要有補償機制,主動發起銀行查詢指令機制。
6.1. txSelect 和confirmSelect 機制
支持事務,傳統的RabbitMq自身的事務和spring機制在高併發下會消耗系統資源出現阻塞
。因此採用可靠性投遞機制,就是補償機制。數據源使用一個,也就是業務操作的DB2和消息記錄操作DB1使用的是一個數據庫源。可以用一個數據庫實例,但是兩個數據庫
最後利用spring DataSourceTransactionManager 在本地進行發送消息,當消息發送失敗時可進行補償。
6.2.消息的冪等性
6.2.1. 非冪等性:
A.可靠性消息投遞機制
B. MQ broker 服務於消費端傳輸消息的過程中的網絡抖動
3.3.2.冪等性設計架構
說明:
- 需要有全局唯一id
- ID路由組件:將信息入庫,因爲單點壓力過大
當然也可以通過redis做持久化