3

Supervisor进程管理工具使用

 2 years ago
source link: https://chegva.com/2453.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Supervisor进程管理工具使用

2017年8月20日 by anzhihe·0评论 · 1,773 人阅读 · 隐藏边栏 · 最后更新: 2019/5/1

1. Supervisor简介[官网]

Supervisor是一个用Python写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是Python进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程。Supervisor 是一个 C/S 模型的程序,supervisord 为 server 端,对应的有 client端:supervisorctl和应用程序(即我们要管理的程序),它可以在类unix操作系统让用户来监视和控制后台服务进程的数量,一个很重要的功能就是监控服务的主要后台进程,并在出现问题时自动重启。                                              

2. Supervisor安装配置

2.1 使用setuptools安装(安装和配置时需使用root权限)

pip install supervisor
easy_install supervisor
如果是 Ubuntu 系统,还可以使用 apt-get 安装

2.2 下载安装supervisor

wget https://pypi.python.org/packages/source/s/supervisor/supervisor-3.0b1.tar.gz
tar -zxvf supervisor-3.0b1.tar.gz
cd supervisor-3.0b1
python setup.py install

2.3 初始化配置文件

echo_supervisord_conf > /etc/supervisord.conf
# 此命令会在 /etc/下创建一个示例配置文件

2.4 启动supervisor

运行supervisor
supervisord -c /etc/supervisord.conf

# 如果不指定配置文件
supervisord

# 那么配置文件会依次再下面的文件夹中寻找
# $CWD/supervisord.conf
# $CWD/etc/supervisord.conf
# /etc/supervisord.conf
设置supervisor启动文件
vi /etc/init.d/supervisord

#!/bin/bash
#
# supervisord   This scripts turns supervisord on
#
# Author:       Mike McGrath <[email protected]> (based off yumupdatesd)
#               Jason Koppe <[email protected]> adjusted to read sysconfig,
#                   use supervisord tools to start/stop, conditionally wait
#                   for child processes to shutdown, and startup later
#               Mikhail Mingalev <[email protected]> Merged
#                   redhat-init-jkoppe and redhat-sysconfig-jkoppe, and
#                   made the script "simple customizable".
#               Brendan Maguire <[email protected]> Added OPTIONS to
#                   SUPERVISORCTL status call
#
# chkconfig:    345 83 04
#
# description:  supervisor is a process control utility.  It has a web based
#               xmlrpc interface as well as a few other nifty features.
#               Script was originally written by Jason Koppe <[email protected]>.
#

# source function library
. /etc/rc.d/init.d/functions

set -a

PREFIX=/usr

SUPERVISORD=$PREFIX/bin/supervisord
SUPERVISORCTL=$PREFIX/bin/supervisorctl

PIDFILE=/var/run/supervisord.pid
LOCKFILE=/var/lock/subsys/supervisord

OPTIONS="-c /etc/supervisord.conf"

# unset this variable if you don't care to wait for child processes to shutdown before removing the $LOCKFILE-lock
WAIT_FOR_SUBPROCESSES=yes

# remove this if you manage number of open files in some other fashion
ulimit -n 96000

RETVAL=0


running_pid()
{
    # Check if a given process pid's cmdline matches a given name
    pid=$1
    name=$2
    [ -z "$pid" ] && return 1
    [ ! -d /proc/$pid ] && return 1
    (cat /proc/$pid/cmdline | tr "\000" "\n"|grep -q $name) || return 1
    return 0
}

running()
{
# Check if the process is running looking at /proc
# (works for all users)

    # No pidfile, probably no daemon present
    [ ! -f "$PIDFILE" ] && return 1
    # Obtain the pid and check it against the binary name
    pid=`cat $PIDFILE`
    running_pid $pid $SUPERVISORD || return 1
    return 0
}

start() {
        echo "Starting supervisord: "

        if [ -e $PIDFILE ]; then
        echo "ALREADY STARTED"
        return 1
    fi

    # start supervisord with options from sysconfig (stuff like -c)
        $SUPERVISORD $OPTIONS

    # show initial startup status
    $SUPERVISORCTL $OPTIONS status

    # only create the subsyslock if we created the PIDFILE
        [ -e $PIDFILE ] && touch $LOCKFILE
}

stop() {
        echo -n "Stopping supervisord: "
        $SUPERVISORCTL $OPTIONS shutdown
    if [ -n "$WAIT_FOR_SUBPROCESSES" ]; then
            echo "Waiting roughly 60 seconds for $PIDFILE to be removed after child processes exit"
            for sleep in  2 2 2 2 4 4 4 4 8 8 8 8 last; do
                if [ ! -e $PIDFILE ] ; then
                    echo "Supervisord exited as expected in under $total_sleep seconds"
                    break
                else
                    if [[ $sleep -eq "last" ]] ; then
                        echo "Supervisord still working on shutting down. We've waited roughly 60 seconds, we'll let it do its thing f
rom here"
                        return 1
                    else
                        sleep $sleep
                        total_sleep=$(( $total_sleep + $sleep ))
                    fi

                fi
            done
        fi

        # always remove the subsys. We might have waited a while, but just remove it at this point.
        rm -f $LOCKFILE
}

restart() {
        stop
        start
}

case "$1" in
    start)
        start
        RETVAL=$?
        ;;
    stop)
        stop
        RETVAL=$?
        ;;
    restart|force-reload)
        restart
        RETVAL=$?
        ;;
    reload)
        $SUPERVISORCTL $OPTIONS reload
        RETVAL=$?
        ;;
    condrestart)
        [ -f $LOCKFILE ] && restart
        RETVAL=$?
        ;;
    status)
        $SUPERVISORCTL $OPTIONS status
        if running ; then
            RETVAL=0
        else
            RETVAL=1
        fi
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"
        exit 1
esac

exit $RETVAL

====================================
centos7启动文件,进入目录 /usr/lib/systemd/system/,增加文件 supervisord.service
# supervisord service for systemd (CentOS 7.0+)# by ET-CS (https://github.com/ET-CS)[Unit]
Description=Supervisor daemon

[Service]
Type=forking
ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

3. Supervisor配置详解

3.1 supervisor主要配置

[unix_http_server]
file=/tmp/supervisor.sock   ; (the path to the socket file) 
#UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ; socket file mode (default 0700)
#socket 文件的 mode,默认是 0700
;chown=nobody:nogroup       ; socket file uid:gid owner
#socket 文件的 owner,格式: uid:gid
;username=user              ; (default is no username (open server))
;password=123               ; (default is no password (open server))

[inet_http_server]         ; inet (TCP) server disabled by default
#HTTP 服务器,提供 web 管理界面
port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)
#Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
username=chegva             ; (default is no username (open server))
#登录管理后台的用户名和密码
password=chegva           ; (default is no password (open server))

[supervisord]
logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
#日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
#日志文件大小,超出会 rotate,默认 50MB
logfile_backups=10           ; (num of main logfile rotation backups;default 10)
#日志文件保留备份数量默认 10
loglevel=info                ; (log level;default info; others: debug,warn,trace)
#日志级别,默认 info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
#pid 文件
nodaemon=false               ; (start in foreground if true;default false)
#是否在前台启动,默认是 false,即以 daemon 的方式启动
minfds=1024                  ; (min. avail startup file descriptors;default 1024)
#可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ; (min. avail process descriptors;default 200)
#可以打开的进程数的最小值,默认 200

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
#通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致
;serverurl=http://127.0.0.1:9001 ; 通过 HTTP 的方式连接 supervisord    
;username=chris              ; should be same as http_username if set

[include]
files = relative/directory/*.ini
#可以是 *.conf 或 *.ini

3.2 program 配置

新建一个目录 /etc/supervisor/ 用于存放这些配置文件,相应的,把 /etc/supervisord.conf 里 include 部分的的配置修改一下:

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

假设有个用 Python 和 Flask 框架编写的用户中心系统,取名 usercenter,用 gunicorn (http://gunicorn.org/) 做 web 服务器。项目代码位于 /home/leon/projects/usercenter,gunicorn 配置文件为 gunicorn.py,WSGI callable 是 wsgi.py 里的 app 属性。所以直接在命令行启动的方式可能是这样的:

cd /home/leon/projects/usercenter
gunicorn -c gunicorn.py wsgi:app

现在编写一份配置文件来管理这个进程(需要注意:用 supervisord 管理时,gunicorn 的 daemon 选项需要设置为 False):

[program:usercenter]
directory = /home/leon/projects/usercenter ; 程序的启动目录
command = gunicorn -c gunicorn.py wsgi:app ; 启动命令,可以看出与手动在命令行启动的命令是一样的
autostart = true ; 在 supervisord 启动的时候也自动启动
startsecs = 5 ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true ; 程序异常退出后自动重启
startretries = 3 ; 启动失败自动重试次数,默认是 3
user = leon ; 用哪个用户启动
redirect_stderr = true ; 把 stderr 重定向到 stdout,默认 false
stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 20 ; stdout 日志文件备份数
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /data/logs/usercenter_stdout.log

; 可以通过 environment 来添加需要的环境变量,一种常见的用法是修改 PYTHONPATH
; environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere

一份配置文件至少需要一个 [program:x] 部分的配置,来告诉 supervisord 需要管理那个进程。[program:x] 语法中的 x 表示 program name,会在客户端(supervisorctl 或 web 界面)显示,在 supervisorctl 中通过这个值来对程序进行 start、restart、stop 等操作。

直接在配置文件后添加shadowsocks实例

在/etc/supervisord.conf文件最后添加shadowsocks实例,除了单个进程的控制,还可以配置 group,进行分组管理。如下这一段配置如果配置错误,会导致supervisor的启动失败

[program:shadowsocks]
command = /usr/local/bin/ss-server -c /home/anzhihe/config19.json
user = anzhihe
autostart = true
autoresart = true
stderr_logfile=/home/anzhihe/ss.stderr.log
stdout_logfile=/home/anzhihe/ss.stdout.log
logfile_maxbytes=10MB
logfile_backups=5

# 使新的配置文件生效
supervisorctl update

4. Supervisor进程管理

supervisorctl使用

# 控制所有进程
supervisorctl start all
supervisorctl stop all
supervisorctl restart all
# 控制目标进程
supervisorctl stop shadowsocks
supervisorctl start shadowsocks
supervisorctl restart shadowsocks
# 查看程序状态
supervisorctl status
# 读取有更新(增加)的配置文件,不会启动新添加的程序
supervisorctl reread
# 重启配置文件修改过的程序,使新的配置文件生效
supervisorctl update

web端管理进程

参考:

http://www.ttlsa.com/linux/using-supervisor-control-program/

anzhihe安志合个人博客,版权所有丨 如未注明,均为原创 丨转载请注明转自:https://chegva.com/2453.html | ☆★★每天进步一点点,加油!★★☆

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK