更新:已实现一个开源版本reloader。
简单定义热升级就是:让运行中的服务改为执行新的程序代码逻辑,且不中断服务。
目前现有的开源热升级程序主要有endless,和beego的grace组件。
经过测试,grace在热升级时,会掐掉当前处理中的连接,自然无法接受。endless的问题在于每次热升级都是创建子进程后,原进程就退出了,这点显然不符合守护进程的要求。
于是自己实现个新的。逻辑参考了endless。其实endless和grace也是相互“借鉴”,相互copy了很多代码。我在“借鉴”时,力求逻辑尽可能简单,自己编写全部代码,并后续完善一些关键细节。
首先要解决多个进程监听同一地址+端口。我首先想到的是nginx、node.js的端口复用方案。但golang尚不支持端口复用。好在golang支持文件描述符和listener的互转,和文件描述符的继承。方案为主进程创建listener,取得文件描述符,子进程再继承listener文件描述符。
新进程应该执行新程序的逻辑。要实现这点,就不能用fork,不然新进程还是执行旧的程序逻辑。
支持守护进程。这点是我重新实现热升级的关键。endless和grace的逻辑是,创建子进程,然后原进程退出。我的方案是一个master进程,一个worker进程。每次只升级worker进程。
master进程与worker进程在外部看起来应该是一体的。这里沿袭了erlang任其崩溃的思想,一个退出,另一个跟随。如果worker进程退出码非0,master进程以相同的退出码结束。
还有很重要的一点,退出worker进程,首先关闭listener,一并关闭listener关联的文件描述符,再等待所有连接关闭。
支持自动升级。这个不是很必要,以后再说。
相比endless,我的实现的另一个优势是:只提供listener接口,而不是ListenAndServe函数。也就是该实现不仅支持http/https,同时支持其它基于tcp的应用层协议,比如grpc。
作者能否开源?
是否支持windows? endless不支持windows
因为是在公司开发的,是否开源还待请示
不支持windows
这是思路,期待开源
https://github.com/facebookgo/grace/tree/master/gracenet
也是一个不错的方案,可以了解一下
谢谢。
简单看了下,思路大同小异。
但多端口的支持太弱,不如我新写的reloader:https://github.com/wencan/reloader