Supervisor 是一个用 Python 实现的进程管理工具,可以很方便地启动,关闭,重启,查看,以及监控进程,当进程由于某种原因崩溃或者被误杀后,可以自动重启并发送事件通知。Supervisor 可谓运维利器,使用 Supervisor 来管理进程,可以提高系统的高可用特性。
随着 Redis 越来越流行,越来越多的公司都使用上了 Redis,因此 Redis 的进程管理就成了很多公司都需要面临的问题,本文介绍如何使用 Supervisor 来管理 Redis 进程。
Supervisor 包括以下四个组件。
supervisord
服务端程序,主要功能是启动 supervisord 服务及其管理的子进程,记录日志,重启崩溃的子进程,等。
supervisorctl
命令行客户端程序,它提供一个类似 shell 的接口,通过 UNIX 域套接字或者 TCP 套接字并使用 XML_RPC 协议与 supervisord 进程进行数据通信。它的主要功能是管理(启动,关闭,重启,查看状态)子进程。
Web Server
实现在界面上管理进程,还能查看进程日志和清除日志。
XML-RPC 接口
可以通过 XML_RPC 协议对 supervisord 进行远程管理,达到和 supervisorctl 以及 Web Server 一样的管理功能。
进程被 Supervisor 管理后,其运行状态的转化图如下图 1 所示:
我们挑几个重要的进程状态来说明。
没有接触过 Supervisor 的朋友可能对上面的描述感到有些抽象,不用担心,经过下面的实践后,会快速理解 Supervisor 涉及的这些名词的。
我们以 CentOS 平台下为例,说明如何使用 Supervisor 这一强大的进程管理工具。
可以使用easy_intall
来安装 Supervisor:
easy_install supervisor
也可以使用pip
来安装 Supervisor:
pip install supervisor
安装过程比较简单,此处我们不再赘述。
安装完毕后,可以使用以下命令来测试安装是否成功:
echo_supervisord_conf
echo_supervisord_conf
将会在终端输出 Supervisor 配置的样例。
为了将 Supervisor 的配置放置到独立的目录中,我们先创建目录:
cd /etc
mkdir supervisor
接着,可以继续使用echo_supervisord_conf
命令,将 Supervisor 样例配置重定向输出到文件文件中:
echo_supervisord_conf > /etc/supervisor/supervisord.conf
这样,我们便生成了 Supervisor 的主配置文件supervisord.conf
。
为了将 Supervisor 管理的进程配置与主配置文件区分开来,我们创建独立的目录来存放进程配置。
cd /etc/supervisor
mkdir conf.d
然后,修改主配置文件 supervisord.conf
,添加以下配置,将 conf.d 目录下的进程配置引入 Supervisor 管理:
[include]
files = ./conf.d/*.ini
为方便测试 Supervisor 的功能,我们编写以下 Python 脚本,并保存为 hello.py。
import time
import sys
while True:
print("hello\n")
sys.stdout.flush()
time.sleep(1)
hello.py 的主要功能是往标准输出中不断地输出 “hello” 字符串。
为将 hello.py 脚本被 Supervisor 接管,我们在 /etc/supervisor/conf.d 目录创建其配置 hello.ini:
[program:hello]
command=python /home/lihao/codes/python/hello.py
stdout_logfile=/home/lihao/codes/python/hello.log
stderr_logfile=/home/lihao/codes/python/hello_error.log
需要指出的是,被 Supervisor 管理的进程,不能使用 daemon 模式,而必须在前台运行,否则会报错。
由于我们需要使用指定目录下的 Supervisor 主配置文件,在运行 Supervisord 时,需要使用-c
参数来指定主配置文件的路径:
supervisord -c /etc/supervisor/supervisord.conf
使用 supervisorctl 可以查看监控的进程状态:
supervisorctl -c /etc/supervisor/supervisord.conf
输出:
hello RUNNING pid 8475, uptime 7:59:46
supervisor>
可以看到,脚本 hello.py 已经运行了起来(当然使用 ps aux | grep hello
也可以看到其进程信息)。打开文件 /home/lihao/codes/python/hello.log,可以看到文件中不断有”hello”输出。
在 supervisorctl 命令行下,也可以使用start
,stop
,restart
,status
,等命令来启动,关闭,重启,查看状态监控的进程,也可以输入help
来查看命令帮助。限于篇幅,此处不再展开,详细的 supervisorctl 命令可以参考:http://www.supervisord.org/running.html#running-supervisorctl。
在说完 Supervisor 的基本使用后,我们来看下如何使用 Supervisor 来管理 Redis 进程。
有了上面的基础,我们很容易写出 Redis 服务进程的 Supervisor 配置:
[program:redis]
command=/usr/local/bin/redis-server
autostart=true
autorestart=true
startsecs=3
使用 supervisorctl reload 载入新的 Redis 配置后,Redis 进程便让 Supervisor 启动了起来。如果需要指定 Redis 的输出日志,可以通过stdout_logfile
配置选项指定,具体也可以参考上述的 hello 例子。
由于 Supervisor 管理的进程不能设置为 daemon 模式,故如果 Redis 无法正常启动,可以查看一下 Redis 的配置,并将daemonize
选项设置为 no。
daemonize no
为了处理机器宕机重启的情况,Redis 服务进程需要实现机器重启后自动重启的功能。 为此,需要配置 supervisord 进程随着机器启动而启动。要实现这一目的 ,可以在 /etc/init 目录下添加 supervisord.conf 文件:
description "supervisord"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec supervisord -n -c /etc/supervisor/supervisord.conf
这样,每当机器重启后,supervisord 进程都会自动启动起来,避免机器每次重启后都需要手工启动 supervisord 进程的操作。Supervisord 进程启动后,接下来会将其管理的进程自动地启动起来。这样,便实现了被 Supervisor 管理的进程随着机器启动而启动的效果。读者可以自行在测试机器上测试一下。
如果需要开启 Web 管理界面功能,需要在supervisord.conf
配置中添加以下配置:
[inet_http_server]
port=*:9001
username=user
password=123
然后,打开浏览器,输入地址 http://127.0.0.1:9001,这时,会弹出输入框,要求输入用户名和密码(用户名:user,密码:123),便可以进入 Supervisor 提供的进程管理界面。
图 2 :Supervisor Web 管理界面
在此界面下,可以对单个进程进行重启,关闭,查看日志等操作,也可以对所有的进程进行重启,关闭等操作。