發布/訂閱
此條目翻譯品質不佳。 (2017年12月15日) |
在軟件架構中,發布/訂閱(Publish–subscribe pattern)是一種消息範式,消息的發送者(稱為發布者)不會將消息直接發送給特定的接收者(稱為訂閱者)。而是將發布的消息分為不同的類別,無需了解哪些訂閱者(如果有的話)可能存在。同樣的,訂閱者可以表達對一個或多個類別的興趣,只接收感興趣的消息,無需了解哪些發布者(如果有的話)存在。
發布/訂閱是消息隊列範式的兄弟,通常是更大的面向消息中間件系統的一部分。大多數消息系統在API中同時支持消息隊列模型和發布/訂閱模型,例如Java消息服務(JMS)。
這種模式提供了更大的網絡可擴展性和更動態的網絡拓撲,同時也降低了對發布者和發布數據的結構修改的靈活性。
消息過濾
[編輯]在發布/訂閱模型中,訂閱者通常接收所有發布的消息的一個子集。選擇接受和處理的消息的過程被稱作過濾。有兩種常用的過濾形式:基於主題的和基於內容的。
在基於主題的系統中,消息被發布到主題或命名通道上。訂閱者將收到其訂閱的主題上的所有消息,並且所有訂閱同一主題的訂閱者將接收到同樣的消息。發布者負責定義訂閱者所訂閱的消息類別。
在基於內容的系統中,訂閱者定義其感興趣的消息的條件,只有當消息的屬性或內容滿足訂閱者定義的條件時,消息才會被投遞到該訂閱者。發布者需要負責對消息進行分類。
一些系統支持兩者的混合:發布者發布消息到主題上,而訂閱者將基於內容的訂閱註冊到一個或多個主題上。
拓撲
[編輯]在許多發布/訂閱系統中,發布者發布消息到一個中間的消息代理,然後訂閱者向該消息代理註冊訂閱,由消息代理來進行過濾。消息代理通常執行存儲轉發的功能將消息從發布者發送到訂閱者。
歷史
[編輯]最早公開描述發布/訂閱系統之一的是Isis Toolkit的「新聞」子系統,1987年,在計算機協會(ACM)的操作系統原理的研討會上,在論文《在分布式系統中利用虛擬同步》[1]中。該文描述的發布/訂閱技術是由Frank Schmuck發明的。
優點
[編輯]鬆耦合
[編輯]- 發布者與訂閱者鬆耦合,甚至不需要知道它們的存在。由於主題才是關注的焦點,發布者和訂閱者可以對系統拓撲結構保持一無所知。各自繼續正常操作而無需顧及對方。在傳統的緊耦合的客戶端-服務器模式中,當服務器進程不運行時,客戶端無法發送消息給服務器,服務器也無法在客戶端不運行時接收消息。許多發布/訂閱系統不但將發布者和訂閱者從位置上解耦,還從時間上解耦他們。中間件分析師對這種發布/訂閱使用的常用策略,是拆卸一個發布者來讓訂閱者處理完積壓的工作(帶寬限制的一種形式)。
可擴展性
[編輯]- 通過並行操作,消息緩存,基於樹或基於網絡的路由等技術,發布/訂閱提供了比傳統的客戶端–服務器更好的可擴展性。然而,在某些類型的緊耦合、高容量的企業環境中,隨着系統規模上升到由上千台服務器組成的數據中心所共享的發布/訂閱基礎架構,現有的供應商系統經常失去這項好處;在這些高負載環境下,發布/訂閱產品的擴展性是一個研究課題。
- 另一方面,在企業環境之外,發布/訂閱範式已經證明了它的可擴展性遠超過一個單一的數據中心,通過網絡聚合協議如RSS和Atom提供互聯網範圍內分發的消息。在交互時,為了能夠即便是用低檔Web服務器也能將消息播出到(可能)數以百萬計的獨立用戶節點,這些聚合協議接受更高的延遲和無保障交付。
缺點
[編輯]發布/訂閱系統最嚴重的問題是其主要優點的副作用:發布者解耦訂閱者。
消息交付問題
[編輯]發布/訂閱系統必須仔細設計,才能提供特定的應用程序可能需要的更強大的系統性能,例如有保障的交付。
- 發布/訂閱系統的中介(broker)可能設計為在指定時間發送消息,隨後便停止嘗試發送,無論是否已收到所有用戶成功接收消息的確認回復。這樣設計的發布/訂閱系統不能保證消息能夠傳遞到所有需要這種有保障交付的應用程序。要達成有保障交付,必須在發布/訂閱架構之外強制執行這種發布者和訂閱者之間在設計上更緊密的耦合(例如,通過要求訂閱者宣布消息已接收)。
- 發布/訂閱系統中的發布者會「假定」訂閱者正在監聽,而實際上可能沒有。一個工廠可能會使用發布/訂閱系統來允許設備發布問題和故障,訂閱者將問題顯示並記錄。如果記錄器失敗(崩潰了),那麼設備故障發布者不一定收到記錄器失敗的通知,發布/訂閱系統的任何設備都不會顯示和記錄錯誤消息。應當指出的是,對於其它消息架構這也是一個設計上的挑戰,例如客戶端/服務器系統。在客戶端/服務器系統中,當一個錯誤記錄器失效,系統將收到跡象。但是,客戶端/服務器系統要處理這個失效,就必須擁有一個在線的冗餘日誌服務器,或者動態生成回退日誌服務器。這就增加了服務端和客戶端以及整個客戶端/服務器架構設計的複雜度。然而,發布/訂閱系統中,在不影響任何其它設備的情況下,精確複製現有日誌器的冗餘日誌記錄訂閱者可以添加到系統,來增加日誌記錄的可靠性。在發布/訂閱系統中,有保障的錯誤消息日誌功能可以逐步添加,隨後實現設備故障信息記錄的簡單基本功能。
在有少量發布者和訂閱節點的小型網絡和低信息量時發布/訂閱能夠自如伸縮。然而,隨着節點和消息量的增長,不穩定性隨之增長,限制了發布/訂閱網絡的最大可擴展性。大規模時吞吐量不穩定的例子包括:
- 負載激增 - 訂閱請求使網絡流量飽和,隨後進入低信息量(未充分利用網絡帶寬)
- 速度變慢 - 越來越多的應用程序使用該系統(即使它們是在不同的發布/訂閱頻道通信)消息量流入單個訂閱者的速度緩慢
使用中介(服務器)的發布/訂閱系統,同意中介發送消息給帶內訂閱者,會引發安全問題。中介可能被愚弄,從而將通知發送給錯誤的客戶端,增大了針對客戶端的服務請求被拒絕的可能性。中介本身可能超載,因為他們分配資源來跟蹤創建的訂閱。
即使不依賴中介的系統,訂閱者也可能可以接收未被授權的數據。未經授權的發布者可能將不正確或損壞的消息引入到發布/訂閱系統。對於廣播或多播消息的系統,這是尤其真實的。加密(例如傳輸層安全性協定(SSL/TLS)),可以防止未經授權的訪問,但不能防止損壞的消息被授權的發布者引入。除了發布/訂閱架構,例如客戶端/服務器系統,也經常碰到授權的消息發送者有惡意行為。
注釋
[編輯]- ^ Birman, K.; Joseph, T. Exploiting virtual synchrony in distributed systems. Proceedings of the eleventh ACM Symposium on Operating systems principles. SOSP '87 (New York, NY, USA: Association for Computing Machinery). 1987-11-01 [2023-07-17]. ISBN 978-0-89791-242-6. doi:10.1145/41457.37515. (原始內容存檔於2023-07-17).
參見
[編輯]外部連結
[編輯]- XMPP XEP-0060: Publish-Subscribe Protocol(頁面存檔備份,存於網際網路檔案館)
- For an open source example which is in production on MSN.com and Microsoft.com, see Distributed Publish/Subscribe Event System(頁面存檔備份,存於網際網路檔案館)
- A REconfigurable Dispatching System (REDS)
- PyPubSub a Python Publish-Subscribe broker for messages *within* an application (NOT network)
- Another open source example written in python: see Python Message Service(頁面存檔備份,存於網際網路檔案館)
- A Ruby open source example: Faye