一、Supervisor简单介绍
supervisor是一个 Client/Server模式的系统,允许用户在类unix操作系统上监视和控制多个进程,或者可以说是多个程序。supervisor与launchd,daemontools,runit等程序有着相同的功能。
与其中某些程序不同的是,它并不作为“id 为 1的进程”而替代init。相反,它用于控制应用程序,像启动其它程序一样。通俗理解就是,把Supervisor服务管理的进程程序,它们作为supervisor的子进程来运行,而supervisor是父进程。supervisor来监控管理子进程的启动关闭和异常退出后的自动启动。
至于为什么要用supervisor来管理进程,是因为相对于linux传统的进程管理(即系统自带的init 进程管理)方式来说,它有很多的优势:
1) 简单方便
通常管理linux进程的时候,一般来说都需要自己编写一个能够实现进程start/stop/restart/reload功能的脚本,然后丢到/etc/init.d/下面。其实这么做有很多不好的地方:
a) 编写这个脚本,耗时耗力。
b) 当这个进程挂掉的时候,linux不会自动重启它的,想要自动重启的话,还要自己另外写一个监控重启脚本。
supervisor则可以完美的解决上面这那两个问题! 那么supervisor怎么解决呢?
a) supervisor管理进程,就是通过fork/exec的方式把这些被管理的进程,当作supervisor的子进程来启动。这样的话,只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去就OK了。这样就省下了自己写脚本管理linux进程的麻烦了。
b) 被管理进程作为supervisor的子进程,当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,所以也就可以对挂掉的子进程进行自动重启了, 至于重启还是不重启,也要看配置文件里面有没有设置autostart=true。
2) 精确
linux对进程状态的反馈有时候不太准确, 也就是说linux进程通常很难获得准确的up/down状态, Pidfiles经常说谎! 而supervisor监控子进程,得到的子进程状态无疑是准确的。supervisord将进程作为子进程启动,所以它总是知道其子进程的正确的up/down状态,可以方便的对这些数据进行查询.
3) 进程分组
进程支持分组启动和停止,也支持启动顺序,即‘优先级’,supervisor允许为进程分配优先级,并允许用户通过supervisorctl客户端发出命令,如“全部启动”和”重新启动所有“,它们以预先分配的优先级顺序启动。还可以将进程分为”进程组“,一组逻辑关联的进程可以作为一个单元停止或启动。进程组supervisor可以对进程组统一管理,也就是说我们可以把需要管理的进程写到一个组里面,然后把这个组作为一个对象进行管理,如启动,停止,重启等等操作。而linux系统则是没有这种功能的,想要停止一个进程,只能一个一个的去停止,要么就自己写个脚本去批量停止。
4) 集中式管理
supervisor管理的进程,进程组信息,全部都写在一个ini格式的文件里就OK了。管理supervisor时, 可以在本地进行管理,也可以远程管理,而且supervisor提供了一个web界面,可以在web界面上监控,管理进程。 当然了,本地,远程和web管理的时候,需要调用supervisor的xml_rpc接口。
5) 可扩展性
supervisor有一个简单的事件(event)通知协议,还有一个用于控制的XML-RPC接口,可以用Python开发人员来扩展构建。
6) 权限
总所周知, linux的进程特别是侦听在1024端口之下的进程,一般用户大多数情况下,是不能对其进行控制的。想要控制的话,必须要有root权限。然而supervisor提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程了。
7) 兼容性,稳定性
supervisor由Python编写,在除Windows操作系统以外基本都支持,如linux,Mac OS x,solaris,FreeBSD系统
二、Supervisor组成部分
1)supervisord: 服务守护进程
supervisor服务器的进程名是supervisord。它主要负责在自己的调用中启动子程序,响应客户端的命令,重新启动崩溃或退出的进程,记录其子进程stdout和stderr的输出,以及生成和处理对应于子进程生命周期中的"event"服务器进程使用的配置文件,通常路径存放在/etc/supervisord.confa中。此配置文件是INI格式的配置文件。
2) supervisorctl:命令行客户端
supervisor命令行的客户端名称是supervisorctl。它为supervisord提供了一个类似于shell的交互界面。使用supervisorctl,用户可以查看不同的supervisord进程列表,获取控制子进程的状态,如停止和启动子进程
3) Web Server:提供与supervisorctl功能相当的WEB操作界面
一个可以通过Web界面来查看和控制进程的状态,默认监听在9091上。
4) XML-RPC Interface:XML-RPC接口
supervisor用于控制的XML-RPC接口
三、Supervisor安装 (YUM安装)
centos系统下可以直接yum安装, 前提是需要下载epel源, 下载地址: http://dl.fedoraproject.org/pub/epel/
centos6系统
========centos6版本系统================== [root@localhost ~]# rpm -ivh epel-release-latest-6.noarch.rpm --force [root@localhost ~]# yum install -y supervisor 开机启动 [root@localhost ~]# chkconfig supervisord on 启动/关闭/重启等操作 [root@localhost ~]# /etc/init.d/supervisord {start|stop|status|restart|reload|force-reload|condrestart}
centos7系统
======centos7版本系统================== [root@localhost ~]# rpm -ivh epel-release-latest-7.noarch.rpm --force [root@localhost ~]# yum install -7 supervisor 开机启动 [root@localhost ~]# systemctl enable supervisord 启动/关闭/重启等操作 [root@localhost ~]# systemctl start/stop/restart supervisord
特别注意另一种安装方式: 除了yum安装方式以外, 我们通过会选用pip或easy_install方式安装supervisor.
centos7下安装 [root@localhost ~]# yum install -y python-setuptools [root@localhost ~]# easy_install supervisor 或者 "pip install supervisor" 配置文件, 将默认配置保存在/etc/supervisord.conf中 [root@localhost ~]# echo_supervisord_conf > /etc/supervisord.conf 启动 [root@localhost ~]# supervisord -c /etc/supervisord.conf [root@localhost ~]# ps -ef|grep /etc/supervisord root 26586 1 0 02:02 ? 00:00:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf root 26588 26184 0 02:02 pts/0 00:00:00 grep --color=auto /etc/supervisord [root@localhost ~]# which supervisord /usr/bin/supervisord [root@localhost ~]# which supervisorctl /usr/bin/supervisorctl如果没有下面文件, 就手动创建 [root@localhost ~]# vim /usr/lib/systemd/system/supervisord.service [Unit] Description=Process Monitoring and Control Daemon After=rc-local.service nss-user-lookup.target [Service] Type=forking ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf ExecReload=/usr/bin/supervisorctl reload ExecStop=/usr/bin/supervisorctl shutdown [Install] WantedBy=multi-user.target 设置755权限 [root@localhost ~]# chmod 755 /usr/lib/systemd/system/supervisord.service 重启服务(多测试几次) [root@localhost ~]# ps -ef|grep /etc/supervisord root 26586 1 0 02:02 ? 00:00:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf root 26933 26184 0 02:08 pts/0 00:00:00 grep --color=auto /etc/supervisord [root@localhost ~]# /usr/bin/supervisorctl shutdown Shut down [root@localhost ~]# ps -ef|grep /etc/supervisord root 26940 26184 0 02:08 pts/0 00:00:00 grep --color=auto /etc/supervisord 由于上面的supervisord进程是使用配置文件手动启动的, 首次要使用下面的命令关闭,然后使用"systemctl start/stop supervisord" 才会生效! 如果第一次不使用下面命令关闭, 而首次就使用"systemctl stop supervisord" 则关闭不了. [root@localhost ~]# systemctl start supervisord [root@localhost ~]# ps -ef|grep /etc/supervisord root 27049 1 0 02:09 ? 00:00:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf root 27052 26184 0 02:09 pts/0 00:00:00 grep --color=auto /etc/supervisord [root@localhost ~]# systemctl stop supervisord [root@localhost ~]# ps -ef|grep /etc/supervisord root 27068 26184 0 02:09 pts/0 00:00:00 grep --color=auto /etc/supervisord [root@localhost ~]# systemctl start supervisord [root@localhost ~]# systemctl restart supervisord [root@localhost ~]# systemctl reload supervisord [root@localhost ~]# ps -ef|grep /etc/supervisord root 27097 1 0 02:09 ? 00:00:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf root 27100 26184 0 02:09 pts/0 00:00:00 grep --color=auto /etc/supervisord 开机启动 [root@localhost ~]# systemctl enable supervisord Created symlink from /etc/systemd/system/multi-user.target.wants/supervisord.service to /usr/lib/systemd/system/superviso#supervisord服务本身模式配置项 #vim /etc/supervisord.conf # 不采用sock连接方式 ;[unix_http_server] ;file=/tmp/supervisor.sock ; the path to the socket file ;chmod=0700 ; socket file mode (default 0700) ;chown=nobody:nogroup ; socket file uid:gid owner ;username=user ; default is no username (open server) ;password=123 ; default is no password (open server) #采用http连接方式, 并设置登录验证信息 [inet_http_server] ; inet (TCP) server disabled by default port=192.168.10.10:9001 ; ip_address:port specifier, *:port for all iface username=user ; default is no username (open server) password=123 ; default is no password (open server)# 添加被监控程序,被监控程序自身非后台运行
(/etc/supervisord.conf 中配置了:[include] files = supervisord.d/*.ini)
/etc/supervisord.d/tornado_handover.ini[group:tornado_handover_system_services] programs=handover_8081,handover_8082,handover_8083,handover_8084 [program:handover_8081] command=/root/anaconda3/bin/python /opt/handover_system/tornado1/handover.py --port=8081 directory=/opt/handover_system/tornado1/ autostart=true autorestart=true startsecs=2 redirect_stderr=true stdout_logfile=/opt/zmd/tornado_log/handover_8081.log [program:handover_8082] command=/root/anaconda3/bin/python /opt/handover_system/tornado1/handover.py --port=8082 directory=/opt/handover_system/tornado1/ autostart=true autorestart=true startsecs=2 redirect_stderr=true stdout_logfile=/opt/zmd/tornado_log/handover_8082.log [program:handover_8083] command=/root/anaconda3/bin/python /opt/handover_system/tornado1/handover.py --port=8083 directory=/opt/handover_system/tornado1/ autostart=true autorestart=true startsecs=2 redirect_stderr=true stdout_logfile=/opt/zmd/tornado_log/handover_8083.log [program:handover_8084] command=/root/anaconda3/bin/python /opt/handover_system/tornado1/handover.py --port=8084 directory=/opt/handover_system/tornado1/ autostart=true autorestart=true startsecs=2 redirect_stderr=true stdout_logfile=/opt/zmd/tornado_log/handover_8084.log