訊息佇列學習筆記(一)

2021-10-02 20:10:47 字數 3154 閱讀 1265

訊息佇列最常被使用的三種場景:非同步處理、流量控制和服務解耦

訊息佇列的適用範圍不僅僅侷限於這些場景,還有包括:作為發布 / 訂閱系統實現乙個微服務級系統間的觀察者模式;連線流計算任務和資料;用於將訊息廣播給大量接收者。

簡單的說,我們在單體應用裡面需要用佇列解決的問題,在分布式系統中大多都可以用訊息佇列來解決。同時我們也要認識到,訊息佇列也有它自身的一些問題和侷限性,包括:引入訊息佇列帶來的延遲問題;增加了系統的複雜度;可能產生資料不一致的問題

一條訊息從生產到消費完成這個過程,可以劃分三個階段:

在生產階段,訊息佇列通過最常用的請求確認機制,來保證訊息的可靠傳遞,正確處理返回值或者捕獲異常,就可以保證這個階段的訊息不會丟失。

儲存階段正常情況下,只要broker在正常執行,就不會出現丟失訊息的問題,但是如果 broker出現了故障,比如程序死掉了或者伺服器宕機了,還是可能會丟失訊息的。如果對訊息的可靠性要求非常高,可以通過配置broker引數來避免因為宕機丟訊息。

在消費階段,不要在收到訊息後就立即傳送消費確認,而是應該在執行完所有消費業務邏輯之後,再傳送消費確認。

冪等性:其任意多次執行所產生的影響均與一次執行的影響相同。

實現冪等性的方法:

利用資料庫的唯一約束實現冪等

為更新的資料設定前置條件

記錄並檢查操作

1.避免訊息積壓

生產端效能優化:

對於傳送訊息的業務邏輯,只需要注意設定合適的併發和批量大小,就可以達到很好的傳送效能

消費端效能優化:

一定要保證消費端的消費效能要高於生產端的傳送效能,這樣的系統才能健康的持續執行。

消費端的效能優化除了優化消費業務邏輯以外,也可以通過水平擴容,增加消費端的併發數來提公升總體的消費效能。特別需要注意的一點是,在擴容 consumer 的例項數量的同時,必須同步擴容主題中的分割槽(也叫佇列)數量,確保consumer的例項數和分割槽數量是相等的。

2.處理訊息積壓

能導致積壓突然增加,最粗粒度的原因,只有兩種:要麼是傳送變快了,要麼是消費變慢了。大部分訊息佇列都內建了監控的功能,只要通過監控資料,很容易確定是哪種原因。

如果是單位時間傳送的訊息增多,比如說是趕上大促或者搶購,短時間內不太可能優化消費端的**來提公升消費效能,唯一的方法是通過擴容消費端的例項數來提公升總體的消費能力。如果短時間內沒有足夠的伺服器資源進行擴容,沒辦法的辦法是,將系統降級,通過關閉一些不重要的業務,減少傳送方傳送的資料量,最低限度讓系統還能正常運轉,服務一些重要業務。

還有一種不太常見的情況,你通過監控發現,無論是傳送訊息的速度還是消費訊息的速度和原來都沒什麼變化,這時候你需要檢查一下你的消費端,是不是消費失敗導致的一條訊息反覆消費這種情況比較多,這種情況也會拖慢整個系統的消費速度。

如果監控到消費變慢了,你需要檢查你的消費例項,分析一下是什麼原因導致消費變慢。優先檢查一下日誌是否有大量的消費錯誤,如果沒有錯誤的話,可以通過列印堆疊資訊,看一下你的消費執行緒是不是卡在什麼地方不動了,比如觸發了死鎖或者卡在等待某些資源上了。

要想使用網路框架的api來傳輸結構化的資料,必須得先實現結構化的資料與位元組流之間的雙向轉換。這種將結構化資料轉換成位元組流的過程,我們稱為序列化,反過來轉換,就是反序列化。

在選擇序列化實現時,需要權衡這樣幾個因素:

1.使用批量訊息提公升服務端處理能力

構建批訊息和解開批訊息分別在傳送端和消費端的客戶端完成,不僅減輕了broker的壓力,最重要的是減少了 broker處理請求的次數,提公升了總體的處理能力。

2.使用順序讀寫提公升磁碟 io 效能

順序讀寫相比隨機讀寫省去了大部分的定址時間,它只要定址一次,就可以連續地讀寫下去,所以說,效能要比隨機讀寫要好很多。kafka就是充分利用了磁碟的這個特性。它的儲存設計非常簡單,對於每個分割槽,它把從producer收到的訊息,順序地寫入對應的 log 檔案中,乙個檔案寫滿了,就開啟乙個新的檔案這樣順序寫下去。消費的時候,也是從某個全域性的位置開始,也就是某乙個 log 檔案中的某個位置開始,順序地把訊息讀出來。

3.利用 pagecache 加速訊息讀寫

kafka在讀寫訊息檔案的時候,充分利用了pagecache的特性。一般來說,訊息剛剛寫入到服務端就會被消費,按照lru的「優先清除最近最少使用的頁」這種策略,讀取的時候,對於這種剛剛寫入的pagecache,命中的機率會非常高。也就是說,大部分情況下,消費讀訊息都會命中 pagecache,帶來的好處有兩個:乙個是讀取的速度會非常快,另外乙個是,給寫入訊息讓出磁碟的 io 資源,間接也提公升了寫入的效能。

4.使用零拷貝技術加速消費流程。

defaultmqproducer的啟動過程

//獲取 mqclientinstance 的例項 mqclientfactory,沒有則自動建立新的例項

this

.mqclientfactory = mqclientmanager.

getinstance()

.getorcreatemqclientinstance

(this

.defaultmqproducer, rpchook)

;//在 mqclientfactory 中註冊自己

boolean registerok = mqclientfactory.

registerproducer

(this

.defaultmqproducer.

getproducergroup()

,this);

if(!registerok)

this

.topicpublishinfotable.

put(

this

.defaultmqproducer.

getcreatetopickey()

,new

topicpublishinfo()

);if(startfactory)..

.

給所有 broker 傳送心跳

this

.mqclientfactory.

sendheartbeattoallbrokerwithlock()

;

kafka 消費模型的幾個要點:

Kafka學習筆記(一) 訊息佇列

二 訊息佇列的應用場景 三 訊息佇列的缺點 四 訊息佇列的兩種模式 訊息 message 是指在應用之間傳送的資料,訊息可以非常簡單,比如只包含文字字串,也可以更複雜,可能包含嵌入物件。訊息佇列 message queue 是一種應用間的通訊方式,訊息傳送後可以立即返回,有訊息系統來確保資訊的可靠專...

UCOS II 訊息佇列學習一

訊息佇列通常可以應用以下兩個地方 1.儲存外部事件 外部事件由中斷收集,然後儲存到佇列。2.串列埠接收程式中的接收迴圈緩衝區,可理解為訊息佇列。使用乙個訊息佇列的步驟如下 1 建立乙個指向訊息陣列的指標和陣列的大小,該指標陣列必須申明為void型別,如下 void myarrayofmsg size...

訊息佇列(一)

訊息佇列與pipe類似,但是存在兩個區別 message boundaries are preserved,so that readers and writes communicate in units of messages,rather than via an undelimited byte ...