最近,公司进行了新的架构设计,原来一个区服一组进程,变成了对外只有一台服,后面 N 组多进程进行服务的模式。于是,管理进程就变成了一个头痛的问题。原来是在写代码的目录里放置各种脚本解决的,关闭脚本,开启脚本,重启脚本,更新脚本,还有一打用来看各种日志的脚本。这些脚本还是严重目录相关的,要执行某些命令,只能 cd 到指定目录执行(或者用硬连接 + 设置脚本所在目录为当前目录解决?whatever)。遇到实际部署的时候,还需要 ssh 到指定机器上,运行指定脚本,有时候还担心服务器起不来,需要人肉 ssh 过去看 status 或者 tail 日志看。

现在,有 supervisor,将所有这些烦恼一扫而光!supervisor 有两个组件:supervisord 和 supervisorctl,组成了 client/server 结构。supervisord 负责读入配置文件,然后以子进程方式启动配置中定义的程序,将对应的 program 进行后台化(daemonize)处理。supervisorctl 则负责和 supervisord 进行沟通,获取运行中的进程信息,包含 pid,uptime 等信息。supervisorctl 既可以通过命令行参数进行控制,又能够直接进入一个特有的 shell,通过这个 shell 管控进程组。这样,既能够让部分同学准确把握进程状况,又能避免放开 shell 权限,一举多得。

以前做服务器逻辑的多并发,采用 gevent 可以很自然对应到逻辑上的并发微线程,但是处理部分游戏逻辑,需要用到锁,有时候还需要跨进程的锁。所以,当时一直很渴望有个网关进程顶在前头,将网络通信先行串行化,然后后台跑起多个不同工作任务的进程,消化不同的数据包。这样,每个进程处理的任务简单,比较容易做到正确和高效。然后没有并发事件,可以避免锁。现在想来,其实这种架构,是将部分业务逻辑的压力,压在了多进程上,名曰分布式处理,实际运行时,对进程的管控需求会提高,增加了运行时管理的难度。比如,一般需要一个 master 管理这种异质进程,控制其生生灭灭。

使用 supervisor,可以简化进程管理这方面的压力。但是,部分跟业务逻辑相关的进程生命周期,还是需要主动干预。哪些情况下,进程被关闭是正常,什么情况下需要重启进程,还是需要费心搞清楚的。幸而 supervisor 给了一个不错的思路。剩下的就是多服务器配置的生成和管理了,希望能找到可靠的开源工具。