简单实现服务器不停机更新的机制
前言
之前接触过某 moba 游戏,除了其丰富的游戏内容之外,对其服务器更新机制非常好奇。他们的服务器很少进行停机更新,大部分是不停机更新内容。这是如何实现的呢?
思路
服务器更新场景,一般是业务代码迭代或者配置表需要重载。moba 游戏一般是一个服务器承载 1 或多个房间,所以热更新机制有可能是这样一个设计:
- 正在使用的服务器
先停止接收新的请求,等待处理完已有的战斗后重启
- 未使用的服务器
有序重启,防止无服务器可用
当然,实现上肯定不是这么简单。如果按照上面的思路来实现,流程如下:
监听热更新的信号。
收到热更新的信号,创建服务器子进程,同时把 Socket 文件描述符传(file descriptor)递给子进程。
启动服务器子进程,启动成功后发送停机信号给父进程。
父进程处理完请求,退出。
实现
定义服务
1 | type Server struct { |
服务逻辑,分别监听 3 个信道: 2-SIGINT, 15-SIGTERM, 1-SIGHUP,启动服务前判断是否子进程,如果是子进程则使用父进程传递进来的文件描述符继续监听。
1 | func NewServer(addr string) (svr *Server) { |
信道处理,2/15 直接关闭服务。如果是 1 则创建子进程,并把当前进程文件描述符传递给子进程。
1 | // fork |
测试效果
版本 1 服务
版本 2 服务
附上示例:server-hot-update