kafka入門讀書筆記——消息引擎系統

顧名思義,系統A發送給消息引擎系統,系統B去消息引擎系統中讀取系統A發送給B的消息。
最基礎的消息引擎就是做這點事的!其中兩個重要的事實:
消息引擎傳輸的對象是消息;
如何傳輸消息屬於消息引擎設計機制的一部分。
既然消息引擎是用於在不同系統之間傳輸消息的,那麼如何設計待傳輸消息的格式從來都是一等一的大事。試問一條消息如何做到信息表達業務語義而無歧義,同時它還要能最大限度地提供可重用性以及通用性?稍微停頓幾秒去思考一下,如果是你,你要如何設計你的消息編碼格式。
一個比較容易想到的是使用已有的一些成熟解決方案,比如使用 CSV、XML 亦或是 JSON;又或者你可能熟知國外大廠開源的一些序列化框架,比如 Google 的 Protocol Buffer 或 Facebook 的 Avro。這些都是很酷的辦法。那麼現在我告訴你 Kafka 的選擇:它使用的是純二進制的字節序列。當然消息還是結構化的,只是在使用之前都要將其轉換成二進制的字節序列。

消息設計出來之後還不夠,消息引擎系統還要設定具體的傳輸協議,即我用什麼方法把消息傳輸出去。常見的有兩種方法:

  • 點對點模型:也叫消息隊列模型。如果拿上面那個“民間版”的定義來說,那麼系統 A 發送的消息只能被系統 B 接收,其他任何系統都不能讀取 A 發送的消息。日常生活的例子比如電話客服就屬於這種模型:同一個客戶呼入電話只能被一位客服人員處理,第二個客服人員不能爲該客戶服務。
  • 發佈 / 訂閱模型:與上面不同的是,它有一個主題(Topic)的概念,你可以理解成邏輯語義相近的消息容器。該模型也有發送方和接收方,只不過提法不同。發送方也稱爲發佈者(Publisher),接收方稱爲訂閱者(Subscriber)。和點對點模型不同的是,這個模型可能存在多個發佈者向相同的主題發送消息,而訂閱者也可能存在多個,它們都能接收到相同主題的消息。生活中的報紙訂閱就是一種典型的發佈 / 訂閱模型。

比較酷的是 Kafka 同時支持這兩種消息引擎模型,專欄後面我會分享 Kafka 是如何做到這一點的。
爲什麼系統 A 不能直接發送消息給系統 B,中間還要隔一個消息引擎呢?

答案就是“削峯填谷”。這四個字簡直比消息引擎本身還要有名氣。

我翻了很多文獻,最常見的就是這四個字。所謂的“削峯填谷”就是指緩衝上下游瞬時突發流量,使其更平滑。特別是對於那種發送能力很強的上游系統,如果沒有消息引擎的保護,“脆弱”的下游系統可能會直接被壓垮導致全鏈路服務“雪崩”。但是,一旦有了消息引擎,它能夠有效地對抗上游的流量衝擊,真正做到將上游的“峯”填滿到“谷”中,避免了流量的震盪。消息引擎系統的另一大好處在於發送方和接收方的鬆耦合,這也在一定程度上簡化了應用的開發,減少了系統間不必要的交互。

說了這麼多,可能你對“削峯填谷”並沒有太多直觀的感受。我還是舉個例子來說明一下 Kafka 在這中間是怎麼去“抗”峯值流量的吧。比如wo我們在購物時,點擊下單後會調用訂單系統生成對應的訂單,而處理該訂單會依次調用下游的多個子系統服務 ,比如調用支付寶和微信支付的接口、查詢你的登錄信息、驗證商品信息等。顯然上游的訂單操作比較簡單,它的 TPS 要遠高於處理訂單的下游服務,因此如果上下游系統直接對接,勢必會出現下游服務無法及時處理上游訂單從而造成訂單堆積的情形。特別是當出現類似於秒殺這樣的業務時,上游訂單流量會瞬時增加,可能出現的結果就是直接壓跨下游子系統服務。

解決此問題的一個常見做法是我們對上游系統進行限速,但這種做法對上游系統而言顯然是不合理的,畢竟問題並不出現在它那裏。所以更常見的辦法是引入像 Kafka 這樣的消息引擎系統來對抗這種上下游系統 TPS 的錯配以及瞬時峯值流量。

還是這個例子,當引入了 Kafka 之後。上游訂單服務不再直接與下游子服務進行交互。當新訂單生成後它僅僅是向 Kafka Broker 發送一條訂單消息即可。類似地,下游的各個子服務訂閱 Kafka 中的對應主題,並實時從該主題的各自分區(Partition)中獲取到訂單消息進行處理,從而實現了上游訂單服務與下游訂單處理服務的解耦。這樣當出現秒殺業務時,Kafka 能夠將瞬時增加的訂單流量全部以消息形式保存在對應的主題中,既不影響上游服務的 TPS,同時也給下游子服務留出了充足的時間去消費它們。這就是 Kafka 這類消息引擎系統的最大意義所在。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章