iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Modern Web

Let's Go! 解剖Go server開發到部署的過程系列 第 20

day 20 - 新增需求:隨時通知目前統計狀況 nsq / websocket 介紹

假設收到一個回饋, 希望能即時把目前的點數狀況反應在操作畫面上, 讓調度員可以隨時掌握點數的狀況來做調度跟分配。

在跳坑Go以前開發的API多是由介接端主動往Server去問資料, 如果想持續更新資料, 介接的服務要自己設定一個時間區間N秒不斷地詢問Server是否有更新, 有拿到更新資料再繼續後續的動作, 這個方式一來是更新不夠即時, 二來是可能會拿回很多次不需要異動的API結果。
後來有了WebSocket, 前端註冊channel就可以收到後端主動發過來的訊息, 讓畫面的即時更新可以更有效率。Go開發之後我們大量使用了NSQ來控制事件的流程, 由起點主動發送事件到NSQ, 再由需要監聽事件的服務自己監聽事件來進行動作。但是NSQ無法讓前端直接收到訊息, 它沒有提供WebSocket支援, 所以如果需要轉發到前端就要有服務負責接收NSQ訊號再把訊息轉到WebSocket, 查看NSQ的issue,看起來似乎也不會有支援webSocket的打算。

簡介一下這兩樣工具:

  • NSQ

    一款Go開發的分散式即時訊息平台, 可以分為三個部分: nsqd, nsqlookupd, nsqadmin; nsqd 負責跟nsqlookupd 註冊topic與接收發送方的訊息, client端會去監聽nsqlookupd上面的TOPIC, 對TOPIC註冊channel, 這樣就可以收到打給nsqd的訊息, nsqadmin則是一個web介面, 可以看到每個TOPIC裡面有幾個channel在監聽, 以及TOPIC&channel收到的訊息數量與堆積的訊息數量等。

    主要有兩個角色: ProducerConsumer
    Producer 是負責發送訊息那一方, Consumer 是接收訊息那一方。

    有幾種安裝方式可參考官網
    或是透過docker 分別跑 nsqd, nsqlookupd, nsqadm也可以。

  • Websocket

    webcosket 是一個網路應用層的通訊協定,是從HTML 5 開始提供的一種讓Client端瀏覽器和Server之間能進行雙向通訊的技術, 主要是用來補足http協定無法持久連線的不足。http協定只有在client端主動發起request時才會建立連線, 等到API回應之後又會斷開連線。Websocket讓瀏覽器對Server註冊頻道之後就可以保持長連線隨時收到Server發送過來的訊息。
    我們團隊主要是使用syhlion/gusher.cluster來做為Websocket轉發的Proxy, 由一個服務負責監聽所有NSQ訊息再轉發給Client端。所以後端的服務只要發送NSQ訊號就好。

使用NSQ發送事件的好處是: 接收方的服務只要對nsqlookupd註冊就可以收到訊息。
發送方握有主動權可以主動通知事件讓監聽TOPIC的服務們在收到事件之後能馬上做出對應的動作, 不需要再像以前一樣不斷地詢問Server是否有事件需要處理, 另外如果是可以分散處理的工作, 服務也可以透過多Pod註冊同一個channel, 各別跟NSQ領取事件來加速處理事件。不過NSQ因為是個別通知的事件,如果發送方在同一時間把大量事件推到NSQ, 並無法保證接收方收到的順序, 這時候可以在訊息內容加上發送時的timestamp做識別。

今天先到這裡, 明天再來實作。


上一篇
day 19 - health check 讓k8s幫忙關懷服務
下一篇
day 21 - NSQ Producer
系列文
Let's Go! 解剖Go server開發到部署的過程30

尚未有邦友留言

立即登入留言