Loading... <div class="tip share">请注意,本文编写于 567 天前,最后修改于 562 天前,其中某些信息可能已经过时。</div> ## supervisor简介 **Supervisor**是用**Python**开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台**daemon**,并监控进程状态,异常退出时能自动重启。它是通过**fork/exec**的方式把这些被管理的进程当作**supervisor**的子进程来启动,这样只要在**supervisor**的配置文件中,把要管理的进程的可执行文件的路径写进去即可。也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。**supervisor**还提供了一个功能,可以为**supervisord**或者每个子进程,设置一个**非root**的**user**,这个**user**就可以管理它对应的进程。 *注:本文以**centos7**为例,**supervisor**版本**3.4.0**。* <!--more--> ## supervisor安装 1.配置好**yum**源后,可以直接安装 ```yum install supervisor``` 2.**Debian/Ubuntu**可通过**apt**安装 ```apt-get install supervisor``` 3.**pip**安装 ```pip install supervisor``` 4.**easy_install**安装 ```easy_install supervisor``` ## supervisor使用 supervisor配置文件:```/etc/supervisord.conf``` *注:supervisor的配置文件默认是不全的,不过在大部分默认的情况下,上面说的基本功能已经满足。* 子进程配置文件路径:```/etc/supervisord.d/``` *注:默认子进程配置文件为ini格式,可在supervisor主配置文件中修改。* ## 配置文件说明 ### supervisor.conf配置文件说明 ``` [unix_http_server] file=/tmp/supervisor.sock ;UNIX socket 文件,supervisorctl 会使用 ;chmod=0700 ;socket文件的权限,默认是0700 ;chown=nobody:nogroup ;socket文件所属用户及组,格式:uid:gid ;[inet_http_server] ;HTTP服务器,提供web管理界面 ;port=127.0.0.1:9001 ;Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性 ;username=user ;登录管理后台的用户名 ;password=123 ;登录管理后台的密码 [supervisord] ; supervisord 全局配置 logfile=/tmp/supervisord.log ;日志文件路径,默认是 $CWD/supervisord.log logfile_maxbytes=50MB ;日志文件大小,超出会rotate,默认 50MB,如果设成0,表示不限制大小 logfile_backups=10 ;日志文件保留备份数量默认10,设为0表示不备份 loglevel=info ;日志级别,默认info,其它: debug,warn,trace pidfile=/tmp/supervisord.pid ;pid 文件路径 nodaemon=false ;是否在前台启动,默认是false,即以 daemon 的方式启动 minfds=1024 ;可以打开的文件描述符的最小值,默认 1024, 最大为4096 minprocs=200 ;可以打开的进程数的最小值,默认 200 ; the below section must remain in the config file for RPC ; (supervisorctl/web interface) to work, additional interfaces may be ; added by defining them in separate rpcinterface: sections [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///tmp/supervisor.sock ;通过UNIX socket连接supervisord,路径与unix_http_server部分的file一致 ;serverurl=http://127.0.0.1:9001 ; 通过HTTP的方式连接supervisord ;[program:theprogramname] ; 定义一个守护进程 ,比如下面的elasticsearch ;command=/bin/cat ; 启动程序使用的命令,可以是绝对路径或者相对路径 ;process_name=%(program_name)s ; 一个python字符串表达式,用来表示supervisor进程启动的这个的名称,默认值是%(program_name)s ;numprocs=1 ; Supervisor启动这个程序的多个实例,如果numprocs>1,则process_name的表达式必须包含%(process_num)s,默认是1 ;directory=/tmp ; supervisord在生成子进程的时候会切换到该目录 ;umask=022 ; umask for process (default None) ;priority=999 ; 权重,可以控制程序启动和关闭时的顺序,权重越低:越早启动,越晚关闭。默认值是999 ;autostart=true ; 如果设置为true,当supervisord启动的时候,进程会自动启动 ;autorestart=true ; 设置为随 supervisord 重启而重启,值可以是false、true、unexpected。false:进程不会自动重启 ;startsecs=10 ; 程序启动后等待多长时间后才认为程序启动成功,默认是10秒 ;startretries=3 ; supervisord尝试启动一个程序时尝试的次数。默认是3 ;exitcodes=0,2 ; 一个预期的退出返回码,默认是0,2。 ;stopsignal=QUIT ; 当收到stop请求的时候,发送信号给程序,默认是TERM信号,也可以是 HUP, INT, QUIT, KILL, USR1, or USR2 ;stopwaitsecs=10 ; 在操作系统给supervisord发送SIGCHILD信号时等待的时间 ;user=chrism ; 如果supervisord以root运行,则会使用这个设置用户启动子程序 ;redirect_stderr=true ; 如果设置为true,进程则会把标准错误输出到supervisord后台的标准输出文件描述符 ;stdout_logfile=/a/path ; 把进程的标准输出写入文件中,如果stdout_logfile没有设置或者设置为AUTO,则supervisor会自动选择一个文件位置 ;stdout_logfile_maxbytes=1MB ; 标准输出log文件达到多少后自动进行轮转,单位是KB、MB、GB。如果设置为0则表示不限制日志文件大小 ;stdout_logfile_backups=10 ; 标准输出日志轮转备份的数量,默认是10,如果设置为0,则不备份 ;stdout_capture_maxbytes=1MB ; 当进程处于stderr capture mode模式的时候,写入FIFO队列的最大bytes值,单位可以是KB、MB、GB ;stdout_events_enabled=false ; 如果设置为true,当进程在写它的stderr ;stderr_logfile=/a/path ; 把进程的错误日志输出一个文件中,除非redirect_stderr参数被设置为true ;stderr_logfile_maxbytes=1MB ; 错误log文件达到多少后自动进行轮转,单位是KB、MB、GB。如果设置为0则表示不限制日志文件大小 ;stderr_logfile_backups=10 ; 错误日志轮转备份的数量,默认是10,如果设置为0,则不备份 ;stderr_capture_maxbytes=1MB ; 当进程处于stderr capture mode模式的时候,写入FIFO队列的最大bytes值,单位可以是KB、MB、GB ;stderr_events_enabled=false ; 如果设置为true,当进程在写它的stderr到文件描述符的时候,PROCESS_LOG_STDERR事件会被触发 ;environment=A=1,B=2 ; 一个k/v对的list列表 ;serverurl=AUTO ; 是否允许子进程和内部的HTTP服务通讯,如果设置为AUTO,supervisor会自动的构造一个url # 这个地方是自定义一个守护进程 [program:elasticsearch] ; 定义一个守护进程 elasticsearch environment=ES_HOME=/usr/local/elasticsearch ; 设置ES_HOME 环境变量 user=elk ; 启动elasticsearch 的用户 directory=/usr/local/elasticsearch ; 进入到这个目录中 command=/usr/local/elasticsearch/bin/elasticsearch ; 执行启动命令 numprocs=1 ; Supervisor启动这个程序的多个实例,如果numprocs>1,则process_name的表达式必须包含%(process_num)s,默认是1 autostart=true ; 设置为随 supervisord 启动而启动 autorestart=true ; 设置为随 supervisord 重启而重启 startretries=3 ; 设置elasticsearch 重启的重试次数 priority=1 ; 权重,可以控制程序启动和关闭时的顺序,权重越低:越早启动,越晚关闭。默认值是999 ;[group:thegroupname] ; 服务组管理,可以将多个服务名写到这里管理(组名自定义) ;programs=progname1,progname2 ; 上面配置好的服务名,比如elasticsearch,kibana,logstash ;priority=999 ; the relative start priority (default 999) ;包含其它配置文件 一般将每个项目的supervisor文件单独编写,并放入到指定目录下,供这里调取使用 [include] files = relative/directory/*.ini ;可以指定一个或多个以.ini结束的配置文件 ``` ### 子进程配置文件说明 给需要管理的子进程(程序)编写一个配置文件,放在```/etc/supervisor.d/```目录下,以**.ini**作为扩展名(每个进程的配置文件都可以单独分拆也可以把相关的脚本放一起)。如任意定义一个和脚本相关的项目名称的选项组(/etc/supervisord.d/test.conf): ``` # 项目名 [program:blog] # /opt/bin/main.py 项目启动文件所在位置 directory=/opt/bin # 脚本执行命令 command=/usr/bin/python main.py -port=9200 # 启动几个进程 numprocs=1 # 启动失败是的最多重试次数 startretries=2 # supervisor启动的时候是否随着同时启动,默认True autostart=true # 自动重启 autorestart=true # 这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。默认值为10 startsecs=10 # 脚本运行的用户身份 user = test # 日志输出 stderr_logfile=/tmp/blog_stderr.log stdout_logfile=/tmp/blog_stdout.log # 把stderr重定向到stdout,默认 false redirect_stderr = true # stdout日志文件大小,默认 50MB stdout_logfile_maxbytes = 20M # stdout日志文件备份数 stdout_logfile_backups = 20 [group:blog] # 服务名 programs=blog # 优先级 数字越高,优先级越高 priority=999 ``` ### 子进程配置示例 demo1: ``` #说明同上 [program:test] directory=/opt/bin command=/opt/bin/test autostart=true autorestart=false stderr_logfile=/tmp/test_stderr.log stdout_logfile=/tmp/test_stdout.log #user = test ``` demo2: ``` [program:vadd_vodc] command=/home/work/.pyenv/versions/3.6/bin/python main.py -debug=True -port=92%(process_num)02d process_name=%(program_name)s-92%(process_num)02d numprocs=1 directory=/home/work/online/src/vadd_vodc/ environment=PATH="/home/work/online/bin" startretries=2 startsecs=5 autostart=yes autorestart=true redirect_stderr=true logfile_maxbytes=100M stdout_logfile=/data/super_log/vadd_vodc.log [group:vadd_vodc] programs=vadd_vodc priority=999 ``` ## supervisor命令说明 ### 常用命令 ```shell supervisorctl status //查看所有进程的状态 supervisorctl stop es //停止es supervisorctl start es //启动es supervisorctl restart //重启es supervisorctl update //配置文件修改后使用该命令加载新的配置 supervisorctl reload //重新启动配置中的所有程序 ``` *注:把**es**换成**all**可以管理配置中的所有进程。直接输入```supervisorctl```进入**supervisorctl**的**shell**交互界面,此时上面的命令不带**supervisorctl**可直接使用。* ### 注意事项 使用**supervisor**进程管理命令之前先启动**supervisord**,否则程序报错。 使用命令```supervisord -c /etc/supervisord.conf```启动。 若是**centos7**: ```shell systemctl start supervisord.service //启动supervisor并加载默认配置文件 systemctl enable supervisord.service //将supervisor加入开机启动项 ``` ### 常见问题 1. **unix:///var/run/supervisor.sock no such file** 问题描述:安装好**supervisor**没有开启服务直接使用**supervisorctl**报的错 解决办法:```supervisord -c /etc/supervisord.conf``` 2. **command中指定的进程已经起来,但supervisor还不断重启** 问题描述:**command**中启动方式为后台启动,导致识别不到**pid**,然后不断重启,这里使用的是**elasticsearch**,**command**指定的是**$path/bin/elasticsearch -d** 解决办法:**supervisor**无法检测后台启动进程的**pid**,而**supervisor**本身就是后台启动守护进程,因此不用担心这个 3. **启动了多个supervisord服务,导致无法正常关闭服务** 问题描述:在运行```supervisord -c /etc/supervisord.conf```之前,直接运行过```supervisord -c /etc/supervisord.d/xx.conf```导致有些进程被多个**superviord**管理,无法正常关闭进程。 解决办法:使用```ps -fe | grep supervisord```查看所有启动过的**supervisord**服务,**kill**相关的进程。 **更多信息请移步Supervisor官网:[http://supervisord.org][1]** > 参考文章:[主要参考文章][2] [参考文章二][3] [1]: http://supervisord.org/ [2]: https://www.jianshu.com/p/0b9054b33db3 [3]: https://www.cnblogs.com/toutou/p/supervisor.html Last modification:July 27, 2021 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 如果觉得我的文章对你有用,请作者喝杯咖啡把~