Supervisor 上手

在服务器上部署的应用,经常需要有,

  • 随系统自动启动的能力;
  • 意外崩溃/退出后自行恢复运行的能力;
  • 便于查看运行状况,以及统一管理的能力。

当然还有其他需求,不过事实上上述的前两条最为基本。Supervisor 是 Python 开发的一个运行于 *nix 系统下的 C/S 结构的管理服务工具。它拥有不止于上述要求的能力。它的 Client 程序为 supervisorctl,长时间运行于后台的守护程序则是 supervisord,后者甚至内置了一个可以连接的 Web Server 供查看服务状况。

superviserd 启动时,可以指定一个配置文件,命令行开关为 -c 加配置文件名。如果没有显示指定,则按下列顺序寻找:

运行起来以后,可以使用 supervisorctl 来查看/控制,状态查看(status all 其实可省略):

全部停止:

全部启动:

Web 相关的设置如下:

设置需改后,要记得重新加载以生效(切记!):

从最佳实践的角度出发,各个需要监控管理的程序最好各自有自己的专属配置,并将之 include 到主配置文件中,这是 *nix 下的常规操作,不赘述。一个程序的配置文件样例如下(仅供参考,不作详解):

自带的 echo_supervisord_conf 命令可以输出非常完整且有详细解释的样例配置文件,可以自行查看。

最后一个问题是,别的程序都被 supervisor 管理了,那它自己呢?显然不能揪着自己的头发把自己拽离地面。鉴于 CentOS 作为服务器过于普遍,以其为示例说明开机启动 Supervisor 服务。

首先, vim /lib/systemd/system/supervisord.service 来创建 Supervisor 的系统服务,

将服务启用:

启动:

停止:

最后,把网上一个小朋友的教训引用过来(虽然 1. 他的叙述很乱,我还略微做了加工;2. 如果按照上文的说明进行配置和操作不应该出现此问题):

确保通过 supervisor 运行的进程只有一个!是的,切记。比如你的操作不是那么的规范:你先通过 supervisord -c /etc/supervisor/supervisord.confsupervisor 启动了,几天后忘记了之前已启动,当通过 supervisorctl status 去看运行状态时,会看到提示 unix:///tmp/supervisor.sock no such file,你就可能会想是不是 supervisord 挂掉了?不管那么多了,先启动吧,于是做了个操作 supervisord。之后看起来服务都正常了,于是干其他事情去了。可能不久就会收到同事的反馈:数据不正常!你忙了一个小时,各种打日志,各种看代码,最终结果却是:有两个进程在跑同一个执行文件!你会发现一个是当前 supervisor 管理的进程,另一个进程的 ppid 和 supervisor 的 pid 不一样!于是你明白了:supervisord 的操作没有杀死旧进程,而是又启动了一个新进程,两个进程同时运行,结果导致你的数据异常。最终你先将旧进程的父进程杀掉,再杀掉旧进程,再 reload supervisor,之后终于恢复正常。从这一波的操作可以看出:
1. 当看到 unix:///tmp/supervisor.sock no such file 时,一定要好好排查,不要着急去启动。即:遇到问题,不要想着重启!
2. 可以使用一些更优雅的方式来运行 supervisor。比如系统是 CentOS,你把 supervisor 做成一个 systemctl 服务就能避免这些问题。
3. reload supervisor 之后,一定记得检查下,是不是只有一个进程在跑!

此案例原始文章在 https://blog.csdn.net/u012375924/article/details/84946987。

另外,之前一直看有人说 Supervisor 不支持 Python 3,刚才去官网查看更新记录,可以看到从版本 4.0 开始,Supervisor 已经开始支持 Python 3(最低版本要求 3.4)。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注