【自动驾驶】9.分布式通信技术之发布订阅,干货满满
分布式通信技術之發布訂閱 原文鏈接
前面我們一起學習了分布式通信中的遠程調用(分布式通信技術之遠程調用:RPC )。遠程調用的核心是在網絡服務層封裝了通信協議、序列化、傳輸等操作,讓用戶調用遠程服務如同進行本地調用一樣。
其實,這種方式就是通過網絡服務層的封裝實現了不同機器上不同進程之間的直接通信,因為是直接通信,所以通過線程阻塞的方式實現同步調用比較容易,因此通常被用于同步調用。比如,機器 1 上的進程 A 調用機器 2 上的進程 B,進程 A 被掛起,進程 B 開始執行,當進程 B 將值返回給 A 時,A 繼續執行。
雖然這種方式也可以用于異步通信,但因為進程之間是直接交互的,所以當進程比較多時,會導致進程維護通信的復雜度非常高,且一個進程通信接口改變,與其通信的進程都會受到影響。
隨著業務和分布式計算規模的逐漸增大和復雜化,遠程調用模型有點心有余力而不足了,為此出現了專門的異步通信模式,也就是消息發布訂閱模式和消息隊列模式。在接下來的兩篇文章中,我將與你詳細講述這兩種通信模式。
什么是發布訂閱?
其實,發布訂閱的思想在我們的生活中隨處可見。
比如,學術屆電子論文的訂閱方式。通常,各個會議方或出版社會將學術論文發布到論文網站(或平臺上,比如 ACM、知網等),然后學生或老師向論文網站訂閱自己感興趣的論文,比如分布式相關的、AI 相關的等。
當會議方或出版社將論文發布到論文網站后,論文網站會根據訂閱信息,將相應的論文推送給訂閱者(比如通過郵件的方式)。這里的會議方或出版社就相當于生產者,負責發布論文,學生或老師就相當于消費者,而論文網站就相當于一個消息中心。
由此可以看出,發布訂閱的三要素是生產者、消費者和消息中心,生產者負責產生數據放到消息中心,消費者向消息中心訂閱自己感興趣的消息,當發布者推送數據到消息中心后,消息中心根據消費者訂閱情況將相關數據推送給對應的訂閱者。這種將數據送到消費者手里的行為,是不是和我們現在常說的“送貨上門”一樣呢?
發布訂閱的原理及應用
這個論文訂閱的例子,充分體現了發布訂閱的思想。接下來,我就與你進一步分析下發布訂閱的原理吧。
1 發布訂閱的基本工作原理
在分布式通信領域中,消息系統一般有兩種典型的模式。一種是點對點模式(P2P,Point to Point),另一種是發布訂閱模式(Pub/Sub,Publish/Subscribe)。接下來,我們就一起看看這兩種模式,以幫助你深入理解發布訂閱模式的原理。
首先,我們一起看一下什么是點對點模式。
生產者將消息發送到消息中心,然后消費者從消息中心取出對應的消息進行消費。消息被消費后,消息中心不再存儲該消息,因此其他消費者無法再消費該消息。也就是說,點對點模式雖然支持多個消費者,但一個消息只能被一個消費者消費,不允許重復消費。
這種模式就好比,限定了每篇論文只能被一個用戶消費,比如現在有一篇分布式相關的論文,這篇論文推送給學生 A 之后,論文網站就必須將其刪除或下架,也就是說其他用戶無法再獲取或閱讀該論文了。(當然實際情況并不是這樣的,這里只是為了方便你理解,我做了相應的假設。)
接下來,我們看一下發布訂閱模式。
生產者可以發送消息到消息中心,而消息中心通常以主題(Topic)進行劃分,每條消息都會有相應的主題,消息會被存儲到自己所屬的主題中,訂閱該主題的所有消費者均可獲得該消息進行消費。
比如圖中假設生產者 1 發布一個 Topic 相關數據或消息,消費者 1~3 均訂閱了該 Topic 消息,則該消息會推送消費者 1~3,也就是說同一個消息被 3 個消費者消費了。
這種模式就好比,不同的方向代表不同的主題,比如分布式領域代表一個主題,當會議方或出版社發布分布式相關的論文時,該論文會被存儲到論文網站的分布式主題下,同時學生或老師也會根據自己感興趣的主題進行訂閱。如果學生 A 訂閱了分布式主題,那么當會議方或出版社發布分布式相關的論文后,會議網站會將這些論文推送給學生 A。
與點對點模式相比,發布訂閱模式中一個消息可以被多個消費者進行消費,這也是和點對點模式的本質區別。
以上就是發布訂閱中的兩種典型模式了
在分布式系統中,通常會為多用戶服務,而多個用戶通常會關注相同類型的消息,因此發布訂閱模式在分布式系統中非常常見。接下來,我再結合經典的分布式發布訂閱消息系統 Kafka 的發布訂閱原理及工作機制,來幫助你鞏固對發布訂閱的理解。
Kafka 發布訂閱原理及工作機制
Kafka 是一種典型的發布訂閱消息系統,其系統架構也是包括生產者、消費者和消息中心三部分。
- 生產者(Producer)負責發布消息到消息中心,比如電子論文的會議方或出版社;
- 消費者(Consumer)向消息中心訂閱自己感興趣的消息,獲得數據后進行數據處理,比如訂閱電子論文的老師或學生;
- 消息中心(Broker)負責存儲生產者發布的消息和管理消費者訂閱信息,根據消費者訂閱信息,將消息推送給消費者,比如論文網站。在 Kafka 中,消息中心本質上就是一組服務器,也可以說是 Kafka 集群。
Kafka 的架構圖,如下所示:
可以看到,Kafka 中除了 Producer、Broker、Consumer 之外,還有一個 ZooKeeper 集群。Zookeeper 集群用來協調和管理 Broker 和 Consumer,實現了 Broker 和 Consumer 的解耦,并為系統提供可靠性保證。
ZooKeeper 集群可以看作是一個提供了分布式服務協同能力的第三方組件,Consumer 和 Broker 啟動時均會向 ZooKeeper 進行注冊,由 ZooKeeper 進行統一管理和協調。
ZooKeeper 中會存儲一些元數據信息,比如對于 Broker,會存儲主題對應哪些分區(Partition),每個分區的存儲位置等;對于 Consumer,會存儲消費組(Consumer Group)中包含哪些 Consumer,每個 Consumer 會負責消費哪些分區等。
接下來,我們看看分區和消費組的原理和作用吧。
從上面的介紹可以看出,Broker 負責存儲消息數據,Consumer 負責消費數據,Consumer 消費數據的能力會影響 Broker 數據存儲是否溢出的問題。若 Consumer 消費太慢,會導致 Broker 存儲溢出,Broker 就會丟棄一部分消息。
因此,Broker 和 Consumer 是 Kafka 的核心。接下來,我將帶你進一步了解 Kafka 中 Broker 和 Consumer 的關鍵技術,如下圖所示:
首先,我們看一下 Broker。
在 Kafka 中,為了解決消息存儲的負載均衡和系統可靠性問題,所以引入了主題和分區的概念。其中,主題是一個邏輯概念,指的是消息類型或數據類型,就好比電子論文案例所講的分布式是一個主題。
而分區是針對主題而言的,指的是一個主題的內容可以被劃分成多個集合,分布在不同的 Broker 上,不同的 Broker 在不同的節點上。這里的集合就是分區,其中同一個分區只屬于一個 Broker。
那么,分區有什么好處呢?
在我看來,分區的好處主要包括如下兩點:
- 實現負載均衡,避免單個 Broker 上的負載過高。比如,Topic 0 被分為 Partiton-0、Partiton-1 和 Partiton-2 三個分區,分別分布在 Broker 0、Broker 1 和 Broker 2 上。這,就使得 Topic 0 的消息可以分布在這 3 個分區中,實現負載均衡。
- 實現消息的備份,從而保證系統的高可靠。比如,Topic 1 包含兩個分區 Partiton-0、Partiton-1,每個分區內容一致,分別存儲在 Broker 0 和 Broker 1 上,借此實現了數據備份。
接下來,我們再看看 Consumer 吧。
Kafka 中的消費組,指的是多個消費者的一個集合。一個消費組中的消費者共同消費主題消息,并且主題中每個消息只可以由消費組中的某一個消費者進行消費。
引入消費組的目的是什么呢?我們知道,在消息過多的情況下,單個消費者消費能力有限時,會導致消費效率過低,從而導致 Broker 存儲溢出,丟棄一部分消息。Kafka 為了解決這個問題,所以引入了消費組。
這樣一來,我們對發布訂閱的基本工作機制就比較清楚了。接下來,我們再結合電商購物平臺的例子,來看看發布訂閱技術的具體應用吧。
發布訂閱實踐應用
假設在電商購物平臺(為了方便理解,我對電商購物平臺做了一定的簡化)中,用戶首先在訂單系統下單,下單后庫存系統會進行出貨,通知系統則負責通知用戶,整個流程可以用發布訂閱的模式進行,如下圖所示:
- 訂單系統對應發布訂閱模式中的生產者,消息中心有個主題專門存放下單信息,每次用戶下單后,訂單系統會向該主題寫入數據;
- 庫存系統和通知系統對應發布訂閱模式中的消費者,它們會向消息中心訂閱下單信息相關的主題;
- 訂單系統向消息中心發布訂單信息后,庫存系統和通知系統都會獲取到相應的下單信息,然后進行各自后續的操作,即庫存系統進行出貨,通知系統通過短信或郵件等方式通知用戶。
接下來,我們總結下發布訂閱模式的關鍵特征吧。
實現了系統解耦,易于維護。生產者 / 發布者只負責消息的發布,不需要知道訂閱者 / 消費者的數量,也不需要知道訂閱者 / 消費者獲取消息用來做什么,而訂閱者 / 消費者也不需要知道什么時候生產者 / 發布者會發布消息。
所以,生產者 / 發布者和訂閱者 / 消費者互相獨立,進而實現了系統解耦,每個部分可以單獨維護,減少了因為生產者和消費者的耦合引入的一些相互影響。比如,如果兩者耦合在一起,當生產者邏輯更改需要修改代碼時,消費者部分的代碼也受影響,因此每個部分單獨維護降低了維護的復雜度。
實現了異步執行,避免高負載。生產者 / 發布者發布消息到消息中心,當消息超過消息中心可以存儲的容量后,消息中心會丟棄掉超出的消息,這樣系統就不會因為消息數量多而導致系統故障。
總結,我首先通過論文訂閱的案例,與你介紹了什么是發布訂閱以及發布訂閱的基本原理,然后介紹了一個經典的分布式發布訂閱消息系統 Kafka,最后以一個電商購物平臺的案例描述了發布訂閱模式的應用場景。希望對你有幫助
下一篇預告:開始進入分布式存儲的相關專題
在公眾號【架構師修煉】菜單中可自行獲取專屬架構視頻資料,無套路分享,包括不限于 java架構、python系列、人工智能系列、架構系列,以及最新面試、小程序、大前端均無私奉獻,你會感謝我的哈
總結
以上是生活随笔為你收集整理的【自动驾驶】9.分布式通信技术之发布订阅,干货满满的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【自动驾驶】6.实时发布订阅协议(RTP
- 下一篇: 【Linux】31. ffmpeg常用命