service的替代:Supervisor——配置和坑

Published 9/14/2019
Modified 2/24/2020
Views 51

对于一个想要长期在后台跑的服务,比如一个 web server,一般有这几种方法:

  • 使用 nohup + &
  • 做成一个 service,使用 sudo service <servicename> <command> 控制
  • 自行实现 daemon
  • 利用 screen 软件,放到一个 screen 里面跑

第一个方法实用性太差;第二个和第三个在能处理好日志时不错,但是其维护起来较为麻烦;最后一个方法是笔者以前常用的方法。

supervisor 是用 python 编写的程序,其能够将非 daemon 程序放到后台运行并监控,还能做到检测到程序挂掉时重新拉起。它使用了 client/server 架构,因此提供了 web UI 以便远程控制(其实有坑)。

web UI

安装

Ubuntu: sudo pip install supervisor

(不建议使用 apt 安装)

配置

安装完成后建立配置文件夹,按照惯例我们放到 /etc/supervisor 路径下。

# 将默认设置导入路径
sudo mkdir -p /etc/supervisor/conf.d
sudo sh -c "echo_supervisord_conf > /etc/supervisor/supervisord.conf"

下面编辑配置:vim /etc/supervisor/supervisord.conf

大部分配置都不需要改,直接将最后的一行改一下:

[include]
files=/etc/supervisor/conf.d/*.ini

对于想要交由 supervisor 托管的程序,在 /etc/supervisor/conf.d 路径下建立文件即可,如

[program:webserver]
directory=/path/to/webserver
command=bash ./run.sh
autostart=true     # 是否随 supervisor 启动
autorestart=true   # 是否挂掉自动拉起
startsecs=3        # 在此时间内退出会被认为失败
startretries=3
user=<username>

配置完成后,启动 supervisor 的 server 端:

sudo supervisord -c /etc/supervisor/supervisor.conf

supervisor 提供了两种方式进行控制:

  • 命令行式,使用 sudo supervisorctl 进入交互模式,也可后跟 command,如: sudo supervisorctl status/start/stop/reload/update
  • Web UI,在坑的部分讲

需要注意的是,supervisor 只支持非 daemon 的程序,也就是说假如你想托管本身就支持 daemon 模式的程序(如 docker),你需要去除运行时的 -d 参数。

下面介绍一下 supervisor 的坑。

它提供了一个 web UI,支持 unix socket 和 http 两种方式。开放之前,先修改一下用户名和密码(*_http_server.username/password 字段)。注意这里有个坑,要同步改一下下面的 supervisorctl.username/password 字段,否则每次 supervisorctl 都要输密码。 (吐槽:明文/裸hash 保存密码……)

改完密码 nginx 直接配置:

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://unix:/tmp/supervisor.sock;
}

配置完一刷新,网关错误,一查log,发现自动建立的文件是 root|root 700的,nginx 没有 socket 的访问权限。进配置文件把权限改成 777,刷新,终于出来了界面。

点一下界面的 refresh 按钮,发现请求被 301 重定向到 http 了……而且是在 header 里面写死了协议,完全忽略了我们传入的 proto 字段。这个问题我翻阅了其文档也没有找到解决方法,最后在 GitHub 发现很多人也遇到这个问题,提出了很多 issue 和 PR,但是不知道为什么,开发者到现在也不愿意解决这个问题。

最后的结果是,这个所谓的 web UI 实际上只能拿来看,并不能实际控制后台的程序……至少,不能安全地在 https 下使用。

0 comments