實現golang程序熱升級

分類:IT技術 時間:2017-02-13

簡單定義熱升級就是:讓運行中的服務改為執行新的程序代碼邏輯,且不中斷服務。

目前現有的開源熱升級程序主要有 endless ,和beego的 grace 組件。

經過測試,grace在熱升級時,會掐掉當前處理中的連接,自然無法接受。endless的問題在於每次熱升級都是創建子進程後,原進程就退出了,這點顯然不符合守護進程的要求。

於是自己實現個新的。邏輯參考了endless。其實endless和grace也是相互“借鑒”,相互copy了很多代碼。我在“借鑒”時,力求邏輯盡可能簡單,自己編寫全部代碼,並後續完善一些關鍵細節。

首先要解決多個進程監聽同一地址+端口。我首先想到的是nginx、node.js的端口復用方案。但golang尚不支持端口復用。好在golang支持文件描述符和listener的互轉,和文件描述符的繼承。方案為主進程創建listener,取得文件描述符,子進程再繼承listener文件描述符。

新進程應該執行新程序的邏輯。要實現這點,就不能用fork,不然新進程還是執行舊的程序邏輯。

支持守護進程。這點是我重新實現熱升級的關鍵。endless和grace的邏輯是,創建子進程,然後原進程退出。我的方案是一個master進程,一個worker進程。每次只升級worker進程。

還有很重要的一點,退出worker進程,首先關閉listener,一並關閉listener關聯的文件描述符,再等待所有連接關閉。

支持自動升級。這個不是很必要,以後再說。

相比endless,我的實現的另一個優勢是:只提供listener接口,而不是ListenAndServe函數。也就是該實現不僅支持http/https,同時支持其它基於tcp的應用層協議,比如grpc。


Tags: listener master grace 程序 接口

文章來源:


ads
ads

相關文章
ads

相關文章

ad