部分较小的项目例如flask,对内部使用,可无需使用web server,直接用flask自带服务即可完成需求,但考虑到直接使用python app.py
启动flask后,运行过程进程可能会退出,因此有必要对其进行监控并自动重启,supervisor可满足需求,加上其用python写成,可以独自进行二次开发(supervisor的代码值得学习)。本文是对以往部分项目进行一个整理,作为参考资料归档。
1、离线安装supervisor supervisor下载地址:
https://files.pythonhosted.org/packages/ca/1f/07713b0e1e34c312450878801d496bce8b9eff5ea9e70d41ff4e299b2df5/supervisor-4.1.0-py2.py3-none-any.whl
setuptools的下载地址:
https://files.pythonhosted.org/packages/d9/de/554b6310ac87c5b921bc45634b07b11394fe63bc4cb5176f5240addf18ab/setuptools-41.6.0-py2.py3-none-any.whl
先安装setuptools1 2 unzip setuptools-41.6.0.zip && cd setuptools-41.6.0 python setup.py install
再安装supervisor
1 2 3 4 5 6 7 unzip supervisor-4.1.0.tar.gz && cd supervisor-4.1.0 python setup.py install # 测试是否安装成功 [root@~d]# python > >> import supervisor > >>
2、配置supervisor环境变量 很多网上教程在安装完supervisor后,都会给出如下提示:
在/etc/supervisor目录下生成配置文件
1 echo_supervisord_conf> /etc/supervisord.conf
但如果echo_supervisord_conf或者supervisord 二进制程序所在目录没有配到PATH环境变量的话,那么提示未找到对应的命令
1 2 [root@wap ~]# echo_supervisord_conf>/etc/supervisord.conf -bash: echo_supervisord_conf: command not found
查找echo_supervisord_conf 在哪个目录下
2.1 PATH的问题 一般会在python的安装目录下,例如/usr/local/python27/bin 或者在编译安装python所设定的路径
[root@wap~]# which python3.5
/usr/local/bin/python3.5
但会有例外:
很多人安装python后,并没有把python的bin路径设到PATH里,而是直接把新安装的python 路径通过软链接的方式覆盖旧python,例如下面所示:
ln -s /usr/bin/python3.5 /usr/bin/python
虽然这种方式在可以启动python3.5,但一旦安装新的库后,这些库所在路径不是位于python3.5目录下,而是位于系统默认的bin目录下,如下面所示:
1 2 [root@wap ~]# ls /usr/bin/ flask python3.5 pyvenv-3.5 pip3 supervisorctl supervisord echo_supervisord_conf
这里flask库和supervisor库都在/usrl/bin/
目录下 而此时查看系统系统的path变量,centos最初始的path配置如下1 2 3 4 5 6 7 # .bash_profile if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/bin export PATH
显然没有加入python的环境变量,修改后如下:
1 2 3 4 5 6 7 # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi PATH=$PATH:$HOME/bin:/usr/bin/ export PATH
到此,supervisor的相关命令可在shell直接使用
1 2 3 4 5 [root@wap ~]# echo_supervisord_conf ; Sample supervisor config file. ; ; For more information on the config file, please see: ......
3、 将supervisor配置成service,并加入开机自启 3.1 加入service 离线安装supervisor后,还需配置开机启动service,这里要注意:
需要将 daemon "supervisord -c /etc/supervisord.conf "
改为daemon "/usr/bin/supervisord -c /etc/supervisord.conf "
完整的service配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 [root@wap ~]# vi /etc/rc.d/init.d/supervisord # !/bin/bash # source function library . /etc/rc.d/init.d/functions RETVAL=0 start() { echo -n $"Starting supervisord: " daemon "/usr/bin/supervisord -c /etc/supervisord.conf " RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/supervisord } stop() { echo -n $"Stopping supervisord: " killproc supervisord echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/supervisord } restart() { stop start } case "$1" in start) start ;; stop) stop ;; restart|force-reload|reload) restart ;; condrestart) [ -f /var/lock/subsys/supervisord ] && restart ;; status) status supervisord RETVAL=$? ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" exit 1 esac exit $RETVAL
修改文件权限为755,并设置开机启动
1 2 chmod 755 /etc/rc.d/init.d/supervisord chkconfig supervisor on
3.2 修改默认的/etc/supervisord.conf 1 2 3 4 5 6 7 8 9 10 11 [unix_http_server] file=/var/run/supervisor.sock [supervisord] logfile=/var/log/supervisor/supervisord.log ; 修改为 /var/log 目录,避免被系统删除 pidfile=/var/run/supervisord.pid ... [supervisorctl] ; 和'unix_http_server'里面的设定匹配 serverurl=unix:///var/run/supervisor.sock
注意:/var/log/supervisor/supervisord.log
需要手动创建
3.4、配置supervisord的web界面 1 2 3 4 [inet_http_server] port=*:36700 username=*** password=***
3.5、配置管理进程 配置管理进程有两种方式,一种是直接在supervisord.conf文件写入相关进程配置,另外一种是在某个目录下,为每个进程单独创建一份配置文件,然后把这些配置文件include到supervisord.conf,已防止supervisord.conf的全局配置被错误修改。
1 2 3 4 5 6 7 8 # /etc/supervisor/config,用于存放全部进程管理的配置文件 [root@wap ~]# mkdir -p /etc/supervisor/config # 在/etc/supervisord.conf全局配置文件中的include参数, # 将/etc/supervisor/config目录添加到include中 [include] files =/etc/supervisor/config/*.ini
这里以配置flask两个小项目作为示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [root@wap ~]# vi /etc/supervisor/config/flask_app_1.init [program:flask_app_1] command=python /opt/flask_app_1/app.py # 日志目录需要手动创建,文件名由supervisor创建 stdout_logfile=/etc/supervisor/logs/flask_app_1.log # stdout日志文件大小,默认50MB,这里设为10M stdout_logfile_maxbytes=10MB # 限制保存最近10个日志 stdout_logfile_backups=10 # 在 supervisord 启动的时候也自动启动 autostart=true # 把stderr重定向到stdout,默认false redirect_stderr = true # 程序异常退出后自动重启 autorestart=true # 启动5秒后若没有异常退出,则认为该服务已经正常启动 startsecs=5 user=root ;默认使用root用户 priority=10 ;该进程的优先级 stopasgroup=true ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程 killasgroup=true ;默认为false,向进程组发送kill信号,包括子进程
flask_app_2同上配置,注意实际使用中,应与相关需求或功能命名。
4、启动supervisor并测试 这里因为已经将supervisor配置成service,故不需要再使用
supervisord -c /etc/supervisord.conf
这样的命令启动supervisor
1 2 3 4 5 6 7 8 9 10 11 [root@wap ~]# service supervisor start Starting supervisord: [ OK ] [root@wap ~]# service supervisor status supervisord (pid 18921) is running... [root@wap ~]# service supervisor stop Stopping supervisord: [ OK ] [root@wap ~]# service supervisor restart Stopping supervisord: [ OK ] Starting supervisord: [ OK ]
以上说明supervisor的service配置是成功的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 查看已经被管理进程,这里有两种方式,一种在web 页面查看与操作,另外一种则用cli方式查看 # cli查看相关被管理进程服务 [root@portal py_apps]# supervisorctl flask_app_1 RUNNING pid 191047, uptime 0:11:04 flask_app_2 RUNNING pid 191047, uptime 0:11:04 supervisor> # 重启几次flask,查看其日志 [root@wap ~]# cat /etc/supervisor/logs/flask_app_1.log * Serving Flask app "app" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Serving Flask app "app" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off
通过web查看和管理进程
5、supervisor分布式管理服务 例如在serverA放了app1,serverB放了app2,serverC放了app3,而且每个server还有自行开发的其他采集模块等,因supervisor只能管理单机上的进程,对于不同服务器上的进程管理,则需要借助其他工具:例如cesi,地址:https://github.com/Gamegos/cesi
。它可以实现跨服务器管理进程。当然我们完全可以基于supervisor进行开发,利用它提供的rpc接口,也可以开发出集群管理工具。但不建议这么做,考虑到还需要主力攻项目,这些通用工具能用第三方可优先使用。本文不再对cesi进行测试。