你用Go語言開發的WebSocket服務端是如何進行熱更新的?

眾所周知,很多網站都已經用上了WebSocket。更新了代碼之後,要是不能熱更新,所有連接都得斷掉等客戶端來重連,假如經常有更新的話,這個代價也太大了。而普通網站的更新頻率都是挺高的,比如Flickr Architecture - High Scalability - 在2007年就已經做到30分鐘就能更新一次了。現在問題來了,你用時下最最流行的Go語言開發的WebSocket服務端是如何進行熱更新的?

求教,真誠的。


現在在用的架構是前端添加負載均衡設備,流量在負載均衡設備上切換至新伺服器處理。舊伺服器可以在新服務承載大部分流量之後強制切換或者等待所有流量切換至新服務後暫停。之前新老架構升級時使用這種基本可以實現比較方便的小流量測試與上線工作。

DNS方案也是一種,不過不是很推薦,我們測試發現DNS生效時間的影響可控性不高,之前切換就出現過幾小時之後用戶DNS仍未生效的情況,原因也比較複雜。

當然這裡不要有一個誤區,就是使用長連接之後連接一定不能斷。實際上在業務長連接過程中連接斷開也是比較正常的情況,一般程序/網頁在業務斷開時都需要嘗試重新連接至伺服器。除非你的服務是有狀態的遊戲場景,否則一般情況下連接斷開對正常功能的影響也是微乎其微的。何況正常情況下遊戲也可以通過重連正常恢復。比如玩著玩著王者榮耀你網路抖動了一下遊戲就不能玩了那用戶早就罵娘了。

當然如果像省掉負載均衡設備也不是不行,藉助SO_REUSEPORT單機實現多進程監聽。老進程不再接受新連接即可。


Swap Production和Staging環境的DNS


一般性的思路是老的服務不關,新的鏈接進來都路由到新服務上。老服務不在接受新鏈接,通知客戶端重連或者等客戶端自己斷開鏈接,全部斷開之後自己退出結束。

具體怎麼做看情況,小打小鬧就換換埠告訴客戶端連到哪,大一點就可能要寫中間件。


長連接後端服務的熱更新、負載均衡之類都挺麻煩。

手頭一個長連接負載均衡做的比較土,約定客戶端每分鐘重新連一次,走 dns 輪詢,相當於每分鐘隨機長連一個後端節點,這樣下線、上線節點一分鐘後能生效,均衡性比較差,但是不需要暴力斷客戶端連接。


通用的幾個方案。

從多到少依次是:

技術不夠架構來湊。

gateway方案。

網遊比較依賴tcp長連,所以他們比較重視這個方案,有一大堆的框架、文章可以參考。

網路不穩重試來湊。

Websocket我一般用於推送領域,網頁im之類比較多。客戶端(瀏覽器)做好斷線重連機制即可。

網遊除外。

網遊基本都是gateway方案。

能力不夠人力來湊。

Reuseport是一個方案,dns是另一個方案。

兩個方案基本原理一致,下掉一部分服務,等流量切換完畢,再更新上線。

實在不夠公告保底。

停機維護。


原生的websocket還是比較難做的,而且在實際使用中各種企業網關也比較難穿透,如果是基於http協議的長輪詢或者stream,配合客戶端的重連機制,手段就很多了。


現在都容器時代了,好像不太需要熱更新了。

或者我不是老司機,不清楚


推薦閱讀:

最新的TIOBE榜單前五十依舊沒有Golang,Golang目前在國內外的生存狀態如何?
在公司項目中使用golang會不會太激進?

TAG:Go語言 | WebSocket |