使用 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 | cd /etc |
接着,可以继续使用echo_supervisord_conf
命令,将 Supervisor 样例配置重定向输出到文件文件中:
echo_supervisord_conf > /etc/supervisor/supervisord.conf
这样,我们便生成了 Supervisor 的主配置文件supervisord.conf
。
为了将 Supervisor 管理的进程配置与主配置文件区分开来,我们创建独立的目录来存放进程配置。
1 | cd /etc/supervisor |
然后,修改主配置文件 supervisord.conf
,添加以下配置,将 conf.d 目录下的进程配置引入 Supervisor 管理:
1 | [include] |
3. 创建管理进程
为方便测试 Supervisor 的功能,我们编写以下 Python 脚本,并保存为 hello.py。
1 | import time |
hello.py 的主要功能是往标准输出中不断地输出 “hello” 字符串。
4. 创建进程配置
为将 hello.py 脚本被 Supervisor 接管,我们在 /etc/supervisor/conf.d 目录创建其配置 hello.ini:
1 | [program:hello] |
- 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 | hello RUNNING pid 8475, uptime 7:59:46 |
可以看到,脚本 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 管理 Redis 进程
在说完 Supervisor 的基本使用后,我们来看下如何使用 Supervisor 来管理 Redis 进程。
Redis 的 Supervisor 配置
有了上面的基础,我们很容易写出 Redis 服务进程的 Supervisor 配置:
1 | [program:redis] |
使用 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 | description "supervisord" |
这样,每当机器重启后,supervisord 进程都会自动启动起来,避免机器每次重启后都需要手工启动 supervisord 进程的操作。Supervisord 进程启动后,接下来会将其管理的进程自动地启动起来。这样,便实现了被 Supervisor 管理的进程随着机器启动而启动的效果。读者可以自行在测试机器上测试一下。
Supervisor Web 管理界面
如果需要开启 Web 管理界面功能,需要在supervisord.conf
配置中添加以下配置:
1 | [inet_http_server] |
然后,打开浏览器,输入地址 http://127.0.0.1:9001,这时,会弹出输入框,要求输入用户名和密码(用户名:user,密码:123),便可以进入 Supervisor 提供的进程管理界面。
图 2 :Supervisor Web 管理界面
在此界面下,可以对单个进程进行重启,关闭,查看日志等操作,也可以对所有的进程进行重启,关闭等操作。
参考资料
- http://www.supervisord.org/
- Python Web 开发实战,董伟明著,电子工业出版社
- http://www.jianshu.com/p/9abffc905645
- http://www.supervisord.org/running.html#running-supervisorctl
- http://supervisord.org/configuration.html
- http://www.supervisord.org/subprocess.html
- https://lincolnloop.com/blog/automatically-running-supervisord-startup/
- https://serverfault.com/questions/96499/how-to-automatically-start-supervisord-on-linux-ubuntu
- https://segmentfault.com/a/1190000003955182