使用 Supervisor 来管理 Redis 进程

Supervisor 是一个用 Python 实现的进程管理工具,可以很方便地启动,关闭,重启,查看,以及监控进程,当进程由于某种原因崩溃或者被误杀后,可以自动重启并发送事件通知。Supervisor 可谓运维利器,使用 Supervisor 来管理进程,可以提高系统的高可用特性。
随着 Redis 越来越流行,越来越多的公司都使用上了 Redis,因此 Redis 的进程管理就成了很多公司都需要面临的问题,本文介绍如何使用 Supervisor 来管理 Redis 进程。

Supervisor 简介

Supervisor 包括以下四个组件。

  • supervisord
    服务端程序,主要功能是启动 supervisord 服务及其管理的子进程,记录日志,重启崩溃的子进程,等。

  • supervisorctl
    命令行客户端程序,它提供一个类似 shell 的接口,通过 UNIX 域套接字或者 TCP 套接字并使用 XML_RPC 协议与 supervisord 进程进行数据通信。它的主要功能是管理(启动,关闭,重启,查看状态)子进程。

  • Web Server
    实现在界面上管理进程,还能查看进程日志和清除日志。
  • XML-RPC 接口
    可以通过 XML_RPC 协议对 supervisord 进行远程管理,达到和 supervisorctl 以及 Web Server 一样的管理功能。

进程被 Supervisor 管理后,其运行状态的转化图如下图 1 所示:


图 1 :子进程状态转移图

我们挑几个重要的进程状态来说明。

  • running:进程处于运行状态
  • starting:Supervisor 收到启动请求后,进程处于正在启动过程中
  • stopped:进程处于关闭状态
  • stopping:Supervisor 收到关闭请求后,进程处于正在关闭过程中
  • backoff:进程进入 starting 状态后,由于马上就退出导致没能进入 running 状态
  • fatal:进程没有正常启动
  • exited:进程从 running 状态退出

没有接触过 Supervisor 的朋友可能对上面的描述感到有些抽象,不用担心,经过下面的实践后,会快速理解 Supervisor 涉及的这些名词的。

Supervisor 初体验

我们以 CentOS 平台下为例,说明如何使用 Supervisor 这一强大的进程管理工具。

1. 安装

可以使用easy_intall来安装 Supervisor:

1
easy_install supervisor

也可以使用pip来安装 Supervisor:

1
pip install supervisor

安装过程比较简单,此处我们不再赘述。

安装完毕后,可以使用以下命令来测试安装是否成功:

1
echo_supervisord_conf

echo_supervisord_conf将会在终端输出 Supervisor 配置的样例。

2. 创建配置目录以及主配置文件

为了将 Supervisor 的配置放置到独立的目录中,我们先创建目录:

1
2
cd /etc
mkdir supervisor

接着,可以继续使用echo_supervisord_conf命令,将 Supervisor 样例配置重定向输出到文件文件中:

echo_supervisord_conf > /etc/supervisor/supervisord.conf

这样,我们便生成了 Supervisor 的主配置文件supervisord.conf

为了将 Supervisor 管理的进程配置与主配置文件区分开来,我们创建独立的目录来存放进程配置。

1
2
cd /etc/supervisor
mkdir conf.d

然后,修改主配置文件 supervisord.conf,添加以下配置,将 conf.d 目录下的进程配置引入 Supervisor 管理:

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

3. 创建管理进程

为方便测试 Supervisor 的功能,我们编写以下 Python 脚本,并保存为 hello.py。

1
2
3
4
5
6
import time
import sys
while True:
print("hello\n")
sys.stdout.flush()
time.sleep(1)

hello.py 的主要功能是往标准输出中不断地输出 “hello” 字符串。

4. 创建进程配置

为将 hello.py 脚本被 Supervisor 接管,我们在 /etc/supervisor/conf.d 目录创建其配置 hello.ini:

1
2
3
4
[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
  • command:运行进程使用的命令
  • stdout_logfile:指定标准输出文件
  • stderr_logfile:标准错误输出文件

需要指出的是,被 Supervisor 管理的进程,不能使用 daemon 模式,而必须在前台运行,否则会报错。

5. 运行 supervisord

由于我们需要使用指定目录下的 Supervisor 主配置文件,在运行 Supervisord 时,需要使用-c参数来指定主配置文件的路径:

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

6. 使用 supervisorctl 管理进程

使用 supervisorctl 可以查看监控的进程状态:

1
supervisorctl -c /etc/supervisor/supervisord.conf

输出:

1
2
hello RUNNING pid 8475, uptime 7:59:46
supervisor>

可以看到,脚本 hello.py 已经运行了起来(当然使用 ps aux | grep hello也可以看到其进程信息)。打开文件 /home/lihao/codes/python/hello.log,可以看到文件中不断有”hello”输出。

在 supervisorctl 命令行下,也可以使用startstoprestartstatus,等命令来启动,关闭,重启,查看状态监控的进程,也可以输入help来查看命令帮助。限于篇幅,此处不再展开,详细的 supervisorctl 命令可以参考:http://www.supervisord.org/running.html#running-supervisorctl

Supervisor 管理 Redis 进程

在说完 Supervisor 的基本使用后,我们来看下如何使用 Supervisor 来管理 Redis 进程。

Redis 的 Supervisor 配置

有了上面的基础,我们很容易写出 Redis 服务进程的 Supervisor 配置:

1
2
3
4
5
[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。

1
daemonize no

Supervisord 开机启动

为了处理机器宕机重启的情况,Redis 服务进程需要实现机器重启后自动重启的功能。 为此,需要配置 supervisord 进程随着机器启动而启动。要实现这一目的 ,可以在 /etc/init 目录下添加 supervisord.conf 文件:

1
2
3
4
5
6
7
description "supervisord"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec supervisord -n -c /etc/supervisor/supervisord.conf

这样,每当机器重启后,supervisord 进程都会自动启动起来,避免机器每次重启后都需要手工启动 supervisord 进程的操作。Supervisord 进程启动后,接下来会将其管理的进程自动地启动起来。这样,便实现了被 Supervisor 管理的进程随着机器启动而启动的效果。读者可以自行在测试机器上测试一下。

Supervisor Web 管理界面

如果需要开启 Web 管理界面功能,需要在supervisord.conf配置中添加以下配置:

1
2
3
4
[inet_http_server]
port=*:9001
username=user
password=123

然后,打开浏览器,输入地址 http://127.0.0.1:9001,这时,会弹出输入框,要求输入用户名和密码(用户名:user,密码:123),便可以进入 Supervisor 提供的进程管理界面。

图 2 :Supervisor Web 管理界面

在此界面下,可以对单个进程进行重启,关闭,查看日志等操作,也可以对所有的进程进行重启,关闭等操作。

参考资料

  1. http://www.supervisord.org/
  2. Python Web 开发实战,董伟明著,电子工业出版社
  3. http://www.jianshu.com/p/9abffc905645
  4. http://www.supervisord.org/running.html#running-supervisorctl
  5. http://supervisord.org/configuration.html
  6. http://www.supervisord.org/subprocess.html
  7. https://lincolnloop.com/blog/automatically-running-supervisord-startup/
  8. https://serverfault.com/questions/96499/how-to-automatically-start-supervisord-on-linux-ubuntu
  9. https://segmentfault.com/a/1190000003955182