程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Muduo 網絡編程示例(九)簡單的消息廣播服務

Muduo 網絡編程示例(九)簡單的消息廣播服務

編輯:關於C++

本文介紹用 muduo 實現一個簡單的 topic-based 消息廣播服務,這其實是“聊天室”的一個簡單 擴展,不過聊天的不是人,而是分布式系統中的程序。

本文的代碼見 http://code.google.com/p/muduo/source/browse/trunk/examples/hub

在分布式系統中,除了常用的 end-to-end 通信,還有一對多的廣播通信。一提到“廣播”,或許 會讓人聯想到 IP 多播或 IP 組播,這不是本文的主題。本文將要談的是基於 TCP 協議的應用層廣播 。示意圖如下:

上圖中圓角矩形代表程序,"Hub"是一個服務程序,不是網絡集線器,它起到類似集線器 的作用,故而得名。Publisher 和 Subscriper 通過 TCP 協議與 Hub 程序通信。Publisher 把消息發 到某個 topic 上,Subscribers 訂閱該 topic,然後就能收到消息。即 publisher 借助 hub 把消息 廣播給了多個 subscribers。這種 pub/sub 結構的好處在於可以增加多個 Subscriber 而不用修改 Publisher,一定程度上實現了“解耦”(也可以看成分布式的 observer pattern)。 由於走的是 TCP 協議,廣播是基本可靠的,這裡的“可靠”指的是“比 UDP 可靠”,不是“完全可靠”。(思考 :如何避免 Hub 成為 single point of failure?)

為了避免串擾(cross-talk),每個 topic 在同一時間只應該有一個 publisher,hub 不提供 compare-and-swap 操作。

(“可靠 廣播、原子廣播”在分布式系統中有重大意義,是以 replicated state machine 方式實現可靠的分布 式服務的基礎,“可靠廣播”涉及 consensus 算法,超出了本文的范圍。)

應用層廣播在分布 式系統中用處很大,這裡略舉幾例:

1. 體育比分轉播。有 8 片比賽場地正在進行羽毛球比賽 ,每個場地的計分程序把當前比分發送到各自的 topic 上(第 1 號場地發送到 court1,第 2 號發送 到 court2,以此類推)。需要用到比分的程序(賽場的大屏幕顯示,網上比分轉播等等)自己訂閱感 興趣的 topic ,就能及時收到最新比分數據。由於本文實現的不是 100% 可靠廣播,那麼消息應該是 snapshot,而不是 incremental。(換句話說,消息的內容是“現在是幾比幾”,而不是“剛才誰得分 ”。)

2. 負載監控。每台機器上運行一個監控程序,周期性地把本機當前負載(CPU、網絡、 磁盤、溫度)publish 到以 hostname 命名的 topic 上,這樣需要用到這些數據的程序只要在 hub 訂 閱相應的 topic 就能獲得數據,無需與多台機器直接打交道。(為了可靠起見,監控程序發送的消息 裡邊應該包含時間戳,這樣能防止 stale 數據,甚至一定程度上起到心跳的作用。)沿著這個思路, 分布式系統中的服務程序也可以把自己的當前負載發布到 hub 上,供 load balancer 和 monitor 取 用。

協議

為了簡單起見,muduo 的 hub 示例采用以 '/r/n' 分界的文本協議 ,這樣用 telnet 就能測試 hub。協議只有三個命令:

sub /r/n

該命令表示訂閱 ,以後該 topic 有任何跟新都會發給這個 tcp 連接。在 sub 的時候 ,hub 會把該  上最近的消息發給此 subscriber。

unsub /r/n

該命令表示退訂

pub /r/n/r/n

往  發送消息,內容為 。所有訂閱了此  的 subscribers 會收到同樣 的消息“pub /r/n/r/n”

代碼

muduo 示例中的 hub 分為幾個部分:

hub 服務程序,負責一對多的消息分發。它會記住每個 client 訂閱了哪些 topic,只把消息發給 特定的訂閱者。代碼見 http://code.google.com/p/muduo/source/browse/trunk/examples/hub/hub.cc

pubsub 庫,為了方便編寫使用 hub 服務的應用程序,我寫了一個簡單的 client library,用來和 hub 打交道。這個 library 可以訂閱 topic、退訂 topic、往指定 topic 發布消息。代碼見 http://code.google.com/p/muduo/source/browse/trunk/examples/hub/pubsub.h 和 http://code.google.com/p/muduo/source/browse/trunk/examples/hub/pubsub.cc

sub 示例程序,這個命令行程序訂閱一個或多個 topic,然後等待 hub 的數據。代碼 http://code.google.com/p/muduo/source/browse/trunk/examples/hub/sub.cc

pub 示例程序,這個命令行程序往某個 topic 發布一條消息,消息內容由命令行參數指定。代碼 http://code.google.com/p/muduo/source/browse/trunk/examples/hub/pub.cc

一個程序可以既是 publisher 又是 subscriber,而且 pubsub 庫只用一個 tcp 連接(這樣 failover 比較簡便)。

使用范例:

開啟 4 個命令行窗口

在第一個窗口運行 $ hub 9999

在第二個窗口運行 $ sub 127.0.0.1:9999 mytopic

在第三個窗口運行 $ sub 127.0.0.1:9999 mytopic court

在第四個窗口運行 $ pub 127.0.0.1:9999 mytopic "Hello world."  ,這時第二 三號窗口都會打印 “mytopic: Hello world.”,表明收到了 mytopic 這個主題上的消息。

在第四個窗口運行 $ pub 127.0.0.1:9999 court "13:11"  ,這時第三號窗口會 打印 “court: 13:11”,表明收到了 court 這個主題上的消息。第二號窗口沒有訂閱此消息,故無輸 出。

借助這個簡單的 pub/sub 機制,還可以做很多有意思的事情。比如把分布式系統中的程序的一部分 end-to-end 通信改為通過 pub/sub 來做(例如,原來是 A 向 B 發一個 SOAP request,B 通過同一 個 tcp 連接發回 response (分析二者的通信只能通過查看 log 或用 tcpdump 截獲);現在是 A 往 topic_a_to_b 上發布 request,B 在 topic_b_to_a 上發 response),這樣多掛一個 monitoring subscriber 就能輕易地查看通信雙方的溝通情況,很容易做狀態監控與 trouble shooting。

查看本欄目

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved