站内链接:

说明

介绍

Supervisor 是一个进程管理工具,用于监控和管理多个进程。它可以启动、停止、重启和管理进程,并提供监控和自动恢复功能。

Supervisor 的主要目标是确保进程的可靠运行。它可以监视进程的状态、处理进程的异常退出,并在必要时自动重新启动进程,以保持系统的稳定性。Supervisor 还提供了日志记录、进程组管理、进程优先级控制等功能。

使用 Supervisor 可以轻松管理各种进程,例如 Web 服务器、应用程序后台任务、消息队列消费者等。它对于部署和管理复杂的应用程序非常有用,可以确保进程持续运行,并在进程崩溃或异常退出时自动恢复。

Supervisor 使用一个配置文件来定义要管理的进程及其相关配置。配置文件指定了要启动的进程的命令、日志文件路径、启动优先级等信息。通过命令行工具或 Web 界面,可以与 Supervisor 进行交互,管理和监控进程的状态。

总结而言,Supervisor 是一个功能强大的进程管理工具,用于监控、管理和自动恢复多个进程。它提供了方便的方式来管理应用程序的进程,确保它们的稳定性和可靠性。

进程管理

除了 Supervisor 之外,还有一些类似的进程管理工具可供选择,这些工具提供了类似的功能,用于监控和管理进程的运行状态。以下是一些类似 Supervisor 的常见工具:

名字 发布时间 功能详细说明
Supervisor 2005 年 进程管理器,用于监控和管理进程的生命周期
systemd 2010 年 Linux 系统的系统和服务管理器,可以启动、停止和监控后台服务
PM2 2013 年 面向 Node.js 的进程管理器,可以自动重启、负载均衡和监控进程
Forever 2010 年 Node.js 的进程管理工具,可用于启动、停止和监控后台 Node.js 进程
Circus 2011 年 强大的进程和资源管理工具,可实现进程间通信和动态扩展
Monit 2001 年 轻量级的系统监控工具,可监控服务和进程状态
Daemontools 1997 年 进程监控工具集,用于管理和监控系统服务和进程
runit 2001 年 UNIX 系统的进程管理器,用于自动启动和监控服务
God 2008 年 Ruby 编写的进程监控工具,可监控和管理后台进程
systemd-nspawn 2011 年 Linux 系统的轻量级虚拟化工具,可隔离和管理进程

这些工具提供了进程管理、自动重启、监控服务状态、负载均衡和系统资源管理等功能。它们适用于不同的操作系统和编程语言,并在不同的应用场景中发挥作用。具体选择哪个工具取决于项目需求、技术栈和个人偏好等因素。

组件

Supervisor 包含以下主要组件:

  1. Supervisor Daemon(Supervisord):Supervisord 是 Supervisor 的守护进程,负责启动、停止和管理其他进程。它会读取配置文件,监控配置中指定的进程,并根据需要启动、停止、重启和管理这些进程。

  2. Configuration File(supervisord.conf):配置文件是 Supervisor 的主要配置文件,它定义了要管理的进程及其相关配置。配置文件指定了进程的启动命令、日志文件路径、启动优先级等信息。

  3. Process Group:进程组是一组相关的进程的集合。Supervisor 可以将多个进程归为一个进程组,并对进程组进行统一的管理。这样可以方便地批量管理和操作一组进程。见配置文件中[program:NAME]

  4. Process(Program):进程是 Supervisor 管理的基本单位。每个进程对应一个需要监控和管理的实际应用程序或服务。Supervisor 会启动、停止、重启和监控这些进程,并在需要时进行自动恢复。

  5. Event Listener:事件监听器是 Supervisor 的扩展机制,它可以监听 Supervisor 的事件,并在特定事件发生时执行自定义操作。事件监听器可以用于记录日志、发送通知、执行自定义命令等。

  6. Command-Line Interface(supervisorctl):supervisorctl 是 Supervisor 的命令行界面工具,用于与 Supervisor 交互。它提供了管理和控制 Supervisor 进程的命令,可以查看进程状态、启动、停止、重启进程,以及执行其他管理操作。

以上是 Supervisor 的主要组件,它们共同协作,提供了对进程的管理和监控功能。Supervisor 守护进程读取配置文件并启动进程,通过命令行界面或其他工具与 Supervisord 进行交互,实现对进程的控制和管理。

gunicorn

Gunicorn 和 Supervisor 是两个不同的工具,用于不同的用途。

Gunicorn(Green Unicorn)是一个 Python Web 服务器,用于运行 Python Web 应用程序。它使用多进程模型来处理并发请求,适用于部署 Python Web 应用程序并提供高性能和可靠性。Gunicorn 主要关注于 Web 服务器的功能,如请求处理、并发处理和负载均衡。

Supervisor 是一个进程管理工具,用于监控和管理各种进程,包括应用程序进程、后台任务等。它可以启动、停止、重启和管理多个进程,并提供监控和自动恢复功能。Supervisor 可以确保进程的可靠运行,并在进程崩溃或异常退出时自动重启它们。

区别如下:

  • 功能:Gunicorn 专注于作为 Python Web 服务器运行 Web 应用程序,处理 HTTP 请求并提供高性能。而 Supervisor 专注于进程管理,监控和管理各种进程的运行状态和生命周期。
  • 用途:Gunicorn 用于部署和运行 Python Web 应用程序,将其暴露在网络上供客户端访问。Supervisor 用于管理和监控各种进程,不限于 Web 应用程序,可以管理任何类型的进程。
  • 功能覆盖范围:Gunicorn 主要关注 Web 服务器功能,如请求处理和并发处理。Supervisor 则提供更全面的进程管理功能,包括启动、停止、重启、自动恢复、日志记录等。

通常情况下,可以将 Gunicorn 与 Supervisor 结合使用,以实现更完整的部署和管理方案。使用 Supervisor 来管理 Gunicorn 进程,确保 Gunicorn 服务器的可靠性和自动恢复,同时提供其他进程的管理和监控功能。

总结起来,Gunicorn 是用于运行 Python Web 应用程序的 Web 服务器,而 Supervisor 是一个进程管理工具,用于管理和监控各种进程的运行。

配置

安装

  1. MAC 下的安装配置

安装: pip install supervisor

创建配置文件: echo_supervisord_conf > /usr/local/etc/supervisord.ini

增加或者更改 supervisord.ini 配置, 确保目录已经存在:

1
2
[include]
files = /usr/local/etc/supervisord.d/*.ini

创建软连接, 避免之后运行命令时需要额外指定文件路径: ln -sf /usr/local/etc/supervisord.ini /usr/local/etc/supervisord.conf

启动 supervisord: supervisord -c /usr/local/etc/supervisord.ini

调用 client, 查看当前生效的 app: supervisorctl status

  1. Linux 下安装配置

安装: pip install supervisor

创建配置文件: echo_supervisord_conf > /etc/supervisord.conf

增加或者更改 supervisord.conf 配置, 确保目录已经存在:

1
2
[include]
files = /etc/supervisord.d/*.conf

启动 supervisord: supervisord

调用 client, 查看当前生效的 app: supervisorctl status

  1. 命令说明

对 supervisorctl 命令基本参数的介绍, 可以运行命令supervisorctl, 在程序终端里面运行help获取所有Action值.

  • reload: 重新启动 supervisord 服务, 用于增加新的配置之后的重新载入(在更改配置之后必须执行该命令)
  • restart: 重启 group, single program, multiple program, all program
  • update: 重新加载配置

配置

回到最初的地方, supervisor 提出的目的就是为了管理, 控制子程序, 通过/path/supervisord.d/目录下的子配置文件来定义一系列的program, 每一个 program 以一个独立的配置文件存在, 类似 nginx 下每一个domain作为一个独立的配置文件, 这样利于配置(日志等信息的独立分开)和管理.

例如, 启动一个cat应用, 创建配置文件/usr/local/etc/supervisord.d/test_cat:

1
2
[program:testcat]
command = /bin/cat

由 supervisor 生成的每一个子进程会由supervisord来管理整个进程的声明周期, 当子进程死亡时, 会发出SIGCHLD来通知管理员, 关于信号的相关处理, 见 supervisor 的官网介绍supervisor.

  1. [program:x]配置

关于每一个子程序的配置, 可以参考/path/etc/supervisord.conf中的[program:theprogramname]选项中的值, 每一个键值同该节中的设置保持一致, 中文说明见program:x. 下面对每一个选项做一个简要的说明:

  • command: 启动时的运行命令, 该命令即使不依赖 supervisorctl 也是能在终端运行起来的, 命令中路径需要绝对路径, 必须值
  • process_name: 一个 python 字符表达式, 用于表示进程名称, 默认为: %(program_name)s
  • user: 运行程序的账户, 默认为当前用户, 不同的应用需要不同的用户以控制最小权限
  • numprocs: 进程数量, 默认为 1, [program:x]实际配置的是一个进程组, 由 numprocs 和process_name组合决定, 默认情况下仅仅会创建一个x的单进程, 但若配置了numprocs则会以x_00, x_01的格式启动多个进程, 不过实际使用场景很少
  • numprocs_start: 多进程起始偏移量, 默认为 0
  • priority: 程序启停的相对优先级, 在group的关闭, 开启中非常有用.
  • autostart: 是否跟随 supervisord 的启动而启动, 默认为 true
  • exitcodes: 常与 autorestart 一起使用. 当 autostart 设置为 unexpected 时, 如果进程退出时退出码未在此设置的列表中, 则进程重新启动
  • startsecs: 启动后, 程序需要保持运行并考虑成功将进程从 STARTING 状态转换到 RUNNING 状态)的总秒数, 默认 0 则不考虑
  • startretries: 进程启动失败时的串行重启次数

关闭设置

  • stopsignal: 请求停止时的信号
  • stopwaitsecs: 在程序发送体质信号后需要等待多长时间关闭, 见以前写 C 的例子
  • stopasgroup: 在停止时会向同组所有程序发送关闭信号, 默认为 False, 开启时默认 killasgroup 也为 True
  • killasgroup: 在使用 SIGKILL 停止时, 向同组所有成员发送相同信号

日志配置:

  • redirect_stderr: 重定向标准错误, 相当于2>&1命令
  • stdout_logfile: 标准输出日志文件, 对于 docker 中的应用一般将错误输出的 stderr, 该值一般为/dev/stdout
  • stdout_logfile_maxbytes: 自动切割最大值
  • stdout_logfile_backups: 自动切割最大数量
  • stderr_logfile: 错误输出, docker 中的应用一般为/dev/stdout
  • stderr_log_file_maxbytes: 同 stdout
  • stderr_logfile_backups: 自动切割最大数量

目录配置:

  • environment: 设置新的环境变量, 在容器中会经常用到, 设置特有的库的路径
  • directory: 文件路径, 用于替代chdir
  • umask: 进程的 umask

上面仅仅给出常用的配置项, 对于一些偏僻的配置请查看官网文档. 关于 python 字符表达式, 见笔记python format

  1. include 配置

用于表示包含其他配置文件, 用于配置的复用, 其格式一般如下:

1
2
3
[include]
# 空格分隔序列
files = /abs/first.conf /abc/scond.conf

日志

如果 supervisor 本身运行或者在启动 app 时出现错误, 则需要日志, 进程, 端口等信息的查看, 其中 Mac 和其他系统都是根据配置文件来进行检查工作:

1
2
3
4
5
6
7
8
# 查看supervisord本身启动日志
vim /tmp/supervisord.log
# 进程查看
supervisorctl status
# 端口查看
lsof -i:8009
# CPU, MEM查看, 是否僵尸进程
ps -ef|grep supervisor

示例

  1. API 服务

结合 uwsgi, 在 UNIX 环境运行一个 flask API 服务, 整体运行框架如下: supervisor->uwsgi->flask, 设置 uwsgi, 首先确保 uwsgi 能够正常启动 APP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[uwsgi]
uid = bifeng
gid = staff

base = /Users/bifeng/Public/api
chdir = %(base)
home = /Users/bifeng/.virtualenvs/api

wsgi-file = main.py
callable = application

http = 127.0.0.1:3838
stats = 127.0.0.1:9494
logto = %(base)/logs/uwsgi.log

启动 uwsgi, 并请求http://127.0.0.1:3838/:

1
uwsgi --ini uwsgi.ini

在确保 uwsgi 正常运行的前提下, 将 uwsgi program 加入到 supervisor 进行进程控制, 新建文件/usr/local/etc/supervisord.d/api.ini, 增加如下配置:

1
2
3
4
5
6
[program:api]
command = /Users/bifeng/.virtualenvs/webserver/bin/uwsgi --ini /Users/bifeng/Public/crawler-api/uwsgi.ini
; process_name = %(program_name)s_%(process_num)02d
; numprocs = 4
stdout_logfile = /var/log/supervisor/api.log
stderr_logfile = /var/log/supervisor/api_err.log

启动过程如果报错, 需要首先查看 uwsgi 本身的启动日志, 之后才看 supervisor 的日志信息

  1. celery 任务
1
2
3
4
5
6
7
8
9
10
11
12
13
[program:bamboo]
command=/home/bamboo/.pyenv/versions/bamboo-env/bin/gunicorn --timeout 300 -w %(ENV_API_PROCESSES)s --worker-class=gthread --threads=%(ENV_API_THREADS)s --max-requests %(ENV_API_MAX_REQUESTS)s -b0.0.0.0:8000 manage:app
directory=/app/bamboo-shop
user=root
startsecs=0
stopwaitsecs=60
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
environment=LD_LIBRARY_PATH="/home/bamboo/ibm_db-3.0.1/clidriver/lib:/usr/local/lib64/dm"

其中API_PROCESS, API_THREADS等都是环境变量, 以便可以动态设置进程和线程的数量.

参考