Aldebaran

人生最棒的感觉,就是你做到别人说你做不到的事。

0%

使用supervisor管理进程

生田絵梨花 - 白石麻衣

简介

Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。

除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动。

简为什么要用 supervisord?

  • 实现进程的分组管理,比如支持一同启动/停止多个生产者/消费者实例。

  • 进程崩溃的时候可以重启

安装Supervisor

  1. supervisor 是 Python 编写的,所以安装起来也很方便,可以直接用 pip

    注意: supervisor3不支持python3, supervisor4支持python3, python版本不要不低于python2.7。

     $ curl -O https://bootstrap.pypa.io/get-pip.py
     $ python get-pip.py
    
     $ pip install setuptools
     $ pip install -U setuptools
     $ pip install supervisor
    
  2. 初始化配置文件

    安装完 supervisor 之后,可以运行echo_supervisord_conf 命令输出默认的配置项,也可以重定向到一个配置文件.

     $ echo_supervisord_conf > /etc/supervisord.conf
    

    supervisord.conf配置文件详解:

     [unix_http_server]
     file=/tmp/supervisor.sock   ; UNIX socket 文件,supervisorctl 会使用
     ;chmod=0700                 ; socket 文件的 mode,默认是 0700
     ;chown=nobody:nogroup       ; socket 文件的 owner,格式: uid:gid
    
     ;[inet_http_server]         ; HTTP 服务器,提供 web 管理界面
     ;port=127.0.0.1:9001        ; Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
     ;username=user              ; 登录管理后台的用户名
     ;password=123               ; 登录管理后台的密码
    
     [supervisord]
     logfile=/tmp/supervisord.log ; 日志文件,默认是 $CWD/supervisord.log
     logfile_maxbytes=50MB        ; 日志文件大小,超出会 rotate,默认 50MB
     logfile_backups=10           ; 日志文件保留备份数量默认 10
     loglevel=info                ; 日志级别,默认 info,其它: debug,warn,trace
     pidfile=/tmp/supervisord.pid ; pid 文件
     nodaemon=false               ; 是否在前台启动,默认是 false,即以 daemon 的方式启动
     minfds=1024                  ; 可以打开的文件描述符的最小值,默认 1024
     minprocs=200                 ; 可以打开的进程数的最小值,默认 200
    
     ; the below section must remain in the config file for RPC
     ; (supervisorctl/web interface) to work, additional interfaces may be
     ; added by defining them in separate rpcinterface: sections
     [rpcinterface:supervisor]
     supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
    
     [supervisorctl]
     serverurl=unix:///tmp/supervisor.sock ; 通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致
     ;serverurl=http://127.0.0.1:9001 ; 通过 HTTP 的方式连接 supervisord
    
     ; 包含其他的配置文件
     [include]
     files = relative/directory/*.ini    ; 可以是 *.conf 或 *.ini
    
  3. 修改配置文件

    把 /etc/supervisord.conf 里 include 部分的的配置修改一下

     $ mkdir /etc/supervisor
     $ sed -i 's#\;\[include\]#\[include\]#' /etc/supervisord.conf
     $ sed -i '/relative\/directory/a\files = /etc/supervisor/*.ini' /etc/supervisord.conf
    
  4. 启动supervisord

     $ supervisord -c /etc/supervisord.conf 启动supervisord
    
  5. 守护进程

    supervisor在CentOS7/Ubuntu16下面可以使用 systemd的方式实现 开机自启动。

     $ vim /usr/lib/systemd/user/supervisor.service
    
     [Unit]
     Description=supervisor
     After=network.target
    
     [Service]
     Type=forking
     ExecStart=/usr/local/bin/supervisord -c /etc/supervisord.conf
     ExecStop=/usr/local/bin/supervisord $OPTIONS shutdown
     ExecReload=/usr/local/bin/supervisord $OPTIONS reload
     KillMode=process
     Restart=on-failure
     RestartSec=42s
    
     [Install]
     WantedBy=multi-user.target
    

    启动supervisor

     $ systemctl enable supervisor.service
     $ systemctl daemon-reload
     $ systemctl start  supervisor.service
     $ systemctl status supervisor.service
    

Supervisor常用的命令

Supervisord安装完成后有两个可用的命令行supervisor和supervisorctl,命令使用解释如下:

- supervisord,初始启动Supervisord,启动、管理配置中设置的进程。
- supervisorctl stop programxxx,停止某一个进程(programxxx),programxxx为[program:blogdemon]里配置的值,这个示例就是blogdemon。
- supervisorctl start programxxx,启动某个进程
- supervisorctl restart programxxx,重启某个进程
- supervisorctl stop all,停止全部进程,注:start、restart、stop都不会载入最新的配置文件。
- supervisorctl reload,载入最新的配置文件,并按新的配置启动、管理所有进程。
- supervisorctl shutdown 关闭supervisord
- supervisorctl update 更新配置

使用supervisor

举个例子。

下面是两个配置可以参考一下。

[program:shadowsocks]
command = /usr/local/bin/ssserver -c /etc/shadowsocks.json
autostart = true
autorestart = true
startretries = 5
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 20
stdout_logfile = /data/shadowsocks/shadowsocks_access.log
stderr_logfile_maxbytes = 20MB
stderr_logfile_backups = 20
stderr_logfile = /data/shadowsocks/shadowsocks_error.log

[program:awesome]
command     = /usr/bin/env python3 /srv/awesome/www/app.py
directory   = /srv/awesome/www
user        = www-data
startsecs   = 3

redirect_stderr         = true
stdout_logfile_maxbytes = 50MB
stdout_logfile_backups  = 10
stdout_logfile          = /srv/awesome/log/app.log

  • Supervisor 只能管理在前台运行的程序,所以如果应用程序有后台运行的选项,需要关闭。

  • 孤儿进程

    用 Supervisor 托管的程序还会有子进程(如 Tornado),如果只杀死主进程,子进程就可能变成孤儿进程。

    通过这两项配置来确保所有子进程都能正确停止:

      stopasgroup=true
      killasgroup=true
    
  • supervisor中的minfds及minprocs参数用途)

    问题描述:程序报错

      ConnectionError: Error 24 connecting to 127.0.0.1:6379. Too many open files.
    

    先来看看minfds及minprocs这两个参数在supervisor官方文档中的说明

    官方文档地址: http://www.supervisord.org/configuration.html#supervisord-section-values

      minfds
    
      The minimum number of file descriptors that must be available before supervisord will start successfully. A call to setrlimit will be made to attempt to raise the soft and hard limits of the supervisord process to satisfy minfds. The hard limit may only be raised if supervisord is run as root. supervisord uses file descriptors liberally, and will enter a failure mode when one cannot be obtained from the OS, so it’s useful to be able to specify a minimum value to ensure it doesn’t run out of them during execution. This option is particularly useful on Solaris, which has a low per-process fd limit by default.
    
      Default: 1024
      Required: No.
      Introduced: 3.0
    
      minprocs
    
      The minimum number of process descriptors that must be available before supervisord will start successfully. A call to setrlimit will be made to attempt to raise the soft and hard limits of the supervisord process to satisfy minprocs. The hard limit may only be raised if supervisord is run as root. supervisord will enter a failure mode when the OS runs out of process descriptors, so it’s useful to ensure that enough process descriptors are available upon supervisord startup.
    
      Default: 200
      Required: No.
      Introduced: 3.0
    

    大致意思:

    在supervisord成功启动前,最小的文件描述符数字必须是可以使用的。setrlimit参数会试图提高软硬限制来满足supervisord进程的minfds参数值。如果supervisord的运行用户为root,硬限制会被提高。

    supervisord可以自由地使用文件描述符,当无法从系统获取时将进入错误模式,所以它能够指定一个最小值,用于确保它不会在执行过程中用光文件描述符。这个参数在Solaris中特别有用,Solaris默认情况下具有较低的进程文件描述符限制。(默认值1024,参数为数值,在3.0版本加入)

    当进程描述符超出系统运行的进程描述符时,supervisord会进入错误模式,因此,在启动supervisord时,需要确保有足够的进程描述符可用。(默认值200,参数为数值,在3.0版本加入)

    结论:

    supervisord中参数minfds和minprocs决定了supervisord进程及其守护的子进程的Max Processes及Max open files,并且这个limit限制不受系统ulimit所影响。