supervisor的安装与使用

Supervisor的介绍

Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,可以用来实现设置开机自启动及崩溃后自动重启的功能,还可以对进程输出的日志进行管理。

Supervisor 是一个 C/S 模型的程序,supervisord 是server 端,对应的有 client 端:supervisorctl。Supervisor 的配置文件是/etc/supervisor/supervisord.conf,通常情况下我们不需要修改它。在安装完 supervisor 之后,我们可以运行echo_supervisord_conf 命令输出默认的配置项。

 

一、安装

1.apt

sudo apt install supervisor

2.Ubuntu\Debian下安装

sudo apt-get install supervisor

/etc下会生成一个supervisor文件夹,里面包含supervisord.conf配置文件(Supervisor 的配置文件)和conf.d程序配置文件夹(配置各个进程)

3.easy_install工具

easy_install supervisor

4.源码安装

supervisor网址:https://pypi.org/project/supervisor/

选择需要的版本

 
tar -zxvf supervisor-4.0.3.tar.gz

cd supervisor-4.0.3

sudo python3 setup.py install

 

或直接pip install supervisor

mac安装的路径是/Library/Frameworks/Python.framework/Versions/3.6/bin

如上图,sudo echo_supervisord_conf > /etc/supervisor/supervisord.conf 会提示权限不足,可以将配置文件生成在其他目录

sudo echo_supervisord_conf > /Users/qxq/supervisord.conf

然后再sudo mv  /Users/qxq/supervisord.conf  /etc/supervisor/supervisord.conf

或者使用sudo su - root -c "echo_supervisord_conf > /etc/supervisord.conf"

 

二、配置

1.supervisor配置文件supervisord.conf

; Sample supervisor config file.
;
; For more information on the config file, please see:
; http://supervisord.org/configuration.html
;
; Notes:
;  - Shell expansion ("~" or "$HOME") is not supported.  Environment
;    variables can be expanded using this syntax: "%(ENV_HOME)s".
;  - Quotes around values are not supported, except in the case of
;    the environment= options as shown below.
;  - Comments must have a leading space: "a=b ;comment" not "a=b;comment".
;  - Command will be truncated if it looks like a config file comment, e.g.
;    "command=bash -c 'foo ; bar'" will truncate to "command=bash -c 'foo ".

[unix_http_server]
;file=/tmp/supervisor.sock   		; the path to the socket file
file=/var/run/supervisor.sock	; UNIX socket文件,supervisorctl会使用, 修改为/var/run/目录,避免被系统删除
;chmod=0700                 		; socket file mode (default 0700),socket文件的mode,默认是0700
;chown=nobody:nogroup       		; socket file uid:gid owner,socket文件的owner,格式:uid:gid
;username=user              		; default is no username (open server)
;password=123               		; default is no password (open server)

;[inet_http_server]         		; inet (TCP) server disabled by default, HTTP服务器,提供web管理界面
;port=127.0.0.1:9001       		; ip_address:port specifier, *:port for all iface, Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性
;username=user              		; default is no username (open server), 登录管理后台的用户名
;password=123               		; default is no password (open server), 登录管理后台的密码

[supervisord]
;logfile=/tmp/supervisord.log 		; main log file; default $CWD/supervisord.log
logfile=/var/log/supervisor/supervisord.log ; 日志文件,修改为/var/log/supervisor/目录,避免被系统删除
logfile_maxbytes=50MB        		; max main logfile bytes b4 rotation; default 50MB, 日志文件大小,超出会rotate,默认50MB
logfile_backups=10           		; # of main logfile backups; 0 means none, default 10, 日志文件保留备份数量默认10
loglevel=trace                		; log level; default info; others: debug,warn,trace, 日志级别,默认info,其它:debug,warn,trace
;pidfile=/tmp/supervisord.pid 		; supervisord pidfile; default supervisord.pid
pidfile=/var/run/supervisord.pid	; pid文件, 修改为/var/run/目录,避免被系统删除
nodaemon=false               		; start in foreground if true; default false, 是否在前台启动,默认是false,即以daemon的方式启动
minfds=1024                  		; min. avail startup file descriptors; default 1024, 可以打开的文件描述符的最小值,默认1024
minprocs=200                 		; min. avail process descriptors;default 200, 可以打开的进程数的最小值,默认200
;umask=022                   		; process file creation umask; default 022, 处理文件创建umask;默认022

;设置启动supervisord的用户,一般情况下不要轻易用root用户来启动,除非你真的确定要这么做,如果程序配置文件使用的user是root,这里也要设置为root
;user=supervisord            		; setuid to this UNIX account at startup; recommended if root
;identifier=supervisor       		; supervisord identifier, default is 'supervisor', supervisord标识符,默认为'supervisor'
;directory=/tmp              		; default is not to cd during start
;nocleanup=true              		; don't clean up tempfiles at start; default false
;childlogdir=/tmp            		; 'AUTO' child log dir, default $TEMP
;environment=KEY="value"     		; key value pairs to add to environment
;strip_ansi=false            		; strip ansi escape codes in logs; def. false

; The rpcinterface:supervisor 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:x] sections.

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

; The supervisorctl section configures how supervisorctl will connect to
; supervisord.  configure it match the settings in either the unix_http_server
; or inet_http_server section.

[supervisorctl]
;serverurl=unix:///tmp/supervisor.sock 			; use a unix:// URL  for a unix socket
serverurl=unix:///var/run/supervisor.sock	;通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致
;serverurl=http://127.0.0.1:9001 			; use an http:// url to specify an inet socket, 通过 HTTP 的方式连接 supervisord
;username=chris              				; should be same as in [*_http_server] if set, 如果设置与[*_http_server]设置的用户名一样
;password=123                				; should be same as in [*_http_server] if set, 如果设置与[*_http_server]设置的密码一样
;prompt=mysupervisor         				; cmd line prompt (default "supervisor"), 命令行提示符(默认为“supervisor”)
;history_file=~/.sc_history  				; use readline history if available, 如果可用,请使用readline历史记录

; The sample program section below shows all possible program subsection values.	;下面的示例程序小节显示了所有可能的程序子节值。
; Create one or more 'real' program: sections to be able to control them under		;创建一个或多个“真实”程序:能够控制它们的部分
; supervisor.


;[program:theprogramname]
;command=/bin/cat              ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1                    ; number of processes copies to start (def 1)
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=999                  ; the relative start priority (default 999)
;autostart=true                ; start at supervisord start (default: true)
;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
;startretries=3                ; max # of serial start failures when starting (default 3)
;autorestart=unexpected        ; when to restart if exited after running (def: unexpected)
;exitcodes=0                   ; 'expected' exit codes used with autorestart (default 0)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
;killasgroup=false             ; SIGKILL the UNIX process group (def false)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (0 means none, default 10)
;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stdout_syslog=false           ; send stdout to syslog with process name (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (0 means none, default 10)
;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;stderr_syslog=false           ; send stderr to syslog with process name (default false)
;environment=A="1",B="2"       ; process environment additions (def no adds)
;serverurl=AUTO                ; override serverurl computation (childutils)

; The sample eventlistener section below shows all possible eventlistener	; 下面的示例eventlistener部分显示了所有可能的eventlistener
; subsection values.  Create one or more 'real' eventlistener: sections to be	; 分段的价值观。创建一个或多个“真正的”eventlistener: section to be
; able to handle event notifications sent by supervisord.			; 能够处理督导员发送的事件通知

;[eventlistener:theeventlistenername]
;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1                    ; number of processes copies to start (def 1)
;events=EVENT                  ; event notif. types to subscribe to (req'd)
;buffer_size=10                ; event buffer queue size (default 10)
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=-1                   ; the relative start priority (default -1)
;autostart=true                ; start at supervisord start (default: true)
;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
;startretries=3                ; max # of serial start failures when starting (default 3)
;autorestart=unexpected        ; autorestart if exited after running (def: unexpected)
;exitcodes=0                   ; 'expected' exit codes used with autorestart (default 0)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
;killasgroup=false             ; SIGKILL the UNIX process group (def false)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=false         ; redirect_stderr=true is not allowed for eventlisteners
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (0 means none, default 10)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stdout_syslog=false           ; send stdout to syslog with process name (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (0 means none, default 10)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;stderr_syslog=false           ; send stderr to syslog with process name (default false)
;environment=A="1",B="2"       ; process environment additions
;serverurl=AUTO                ; override serverurl computation (childutils)

; The sample group section below shows all possible group values.  Create one	; 下面的示例组部分显示了所有可能的组值。创建一个
; or more 'real' group: sections to create "heterogeneous" process groups.	; 或更多“实际”组:创建“异构”流程组的部分

;[group:thegroupname]
;programs=progname1,progname2  ; each refers to 'x' in [program:x] definitions
;priority=999                  ; the relative start priority (default 999)

; The [include] section can just contain the "files" setting. 
; This setting can list multiple files (separated by whitespace or newlines).
; It can also contain wildcards.  The filenames are interpreted as relative to this file.
; Included files *cannot* include files themselves.
;[include]部分可以只包含“files”设置。
;此设置可以列出多个文件(用空格或换行分隔)。
;它还可以包含通配符。文件名被解释为相对于这个文件。
;包含的文件*不能*包含文件本身。

;[include]
;files = relative/directory/*.ini
[include]				; 包含其他的配置文件
files = /etc/supervisor/conf.d/*.conf	; 可以随意指定,目录不存在请先建立。配置文件可以是 *.conf 或 *.ini

cd /

sudo mkdir supervisor

sudo chmod 777 /supervisor

cd /supervisor

sudo mkdir run

sudo mkdir log

 

2.程序配置文件

放在include指定的files目录中,结尾为指定的.conf或者.ini

配置可以查询supervisor的官方文档 http://supervisord.org/configuration.html

;设置进程的名称,使用 supervisorctl 来管理进程时需要使用该进程名,如果supervisor管理多个项目,需要起不同的进程名称
[program:sd]

;启动程序的命令,可以使用相对路径和参数, 不建议放入/home/user/, 对于非user用户一般情况下是不能访问	; the program (relative uses PATH, can take args)
command=/bin/bash -c 'source venv/bin/activate && python3 manage.py runserver -h0.0.0.0 -p 8001'

;进程名称, 默认为 %(program_name)s,即 [program:x] 中的 x	; process_name expr (default %(program_name)s)
;process_name=%(program_name)s
;要启动的进程数, 默认为1	; number of processes copies to start (def 1)
;numprocs=1

;执行 command 之前,先切换到程序所在的工作目录	; directory to cwd to before exec (def no cwd)
directory=/Users/qxq/Desktop/ScreenDisplay/

;进程掩码, 默认无, 掩码:--- -w- -w-, 转换后rwx r-x w-x	; umask for process (default None)
;umask=022
;优先级, 值越高, 最后启动, 最先被关闭, 默认值999	; the relative start priority (default 999)
;priority=999
;supervisor启动的时候是否随着同时启动,默认True	; start at supervisord start (default: true)
;autostart=true
;这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。默认值为1	; # of secs prog must stay up to be running (def. 1)
;startsecs=1
;启动失败自动重试次数,默认是3
;startretries=3                	; max # of serial start failures when starting (default 3)

;设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。默认unexpected,如果为false的时候,无论什么情况下,都不会被重新启动,如果为unexpected,只有当进程的退出码不在下面的exitcodes里面定义的才会重启,如果是True会自动重启	; when to restart if exited after running (def: unexpected)
autorestart=true

;当退出码是0时, 执行重启, 默认值0, 配合上一条使用	; 'expected' exit codes used with autorestart (default 0)
;exitcodes=0

;进程停止信号,可以为TERM, HUP, INT, QUIT, KILL, USR1, or USR2,默认TERM
;中断:INT(类似于Ctrl+C)(kill -INT pid),退出后会将写文件或日志(推荐)
;终止:TERM(kill -TERM pid) //信号量参考文章(http://c.biancheng.net/cpp/html/2784.html)
;挂起:HUP(kill -HUP pid),注意与Ctrl+Z/kill -stop pid不同
;从容停止:QUIT(kill -QUIT pid)
;KILL, USR1, USR2其他见命令(kill -l),说明1
;stopsignal=QUIT               	; signal used to kill process (default TERM)
;stopwaitsecs=10               	; max num secs to wait b4 SIGKILL (default 10)	;等待b4 SIGKILL的最大秒数(默认为10)
;stopasgroup=false             	; send stop signal to the UNIX process group (default false)	; 向UNIX进程组发送停止信号(默认为false)
;killasgroup=false             	; SIGKILL the UNIX process group (def false)	; SIGKILL UNIX进程组(默认为false)

;使用哪个用户来启动该进程,默认当前用户,如果是root用户需要再supervisor的配置文件中配置		; setuid to this UNIX account to run the program,
;user=chrism

;redirect_stderr=false          ; redirect proc stderr to stdout (default false), 把 stderr 重定向到 stdout,默认 false
;日志输出路径,如果输出内容不多可以指定这个并把上面的重定向打开, 需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord会自动创建日志文件)
;stdout_logfile=/a/path		; stdout log path, NONE for none; default AUTO,
;stdout_logfile_maxbytes=1MB   	; max # logfile bytes b4 rotation (default 50MB), 日志文件大小,默认 50MB
;stdout_logfile_backups=10     	; # of stdout logfile backups (0 means none, default 10), 日志文件备份数, 默认10个
;stdout_capture_maxbytes=1MB   	; number of bytes in 'capturemode' (default 0), 'capturemode'中的字节数(默认为0)
;stdout_events_enabled=false   	; emit events on stdout writes (default false), 在stdout写操作上发出事件(默认为false)
;stdout_syslog=false           	; send stdout to syslog with process name (default false), 发送stdout到进程名为syslog的系统日志(默认为false)

;错误日志路径, 需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord会自动创建日志文件)
stderr_logfile=/Users/qxq/Desktop/ScreenDisplay/supervisor_log.log	; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB), 日志文件大小,默认 50MB
;stderr_logfile_backups=10     ; # of stderr logfile backups (0 means none, default 10), 日志文件备份数, 默认10个
;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0), 'capturemode'中的字节数(默认为0)
;stderr_events_enabled=false   ; emit events on stderr writes (default false), 在stderr写操作上发出事件(默认为false)
;stderr_syslog=false           ; send stderr to syslog with process name (default false), 使用进程名将stderr发送到syslog(默认为false)
;environment=A="1",B="2"       ; process environment additions (def no adds)	; 可以通过environment来添加需要的环境变量,一种常见的用法是修改PYTHONPATH
;serverurl=AUTO                ; override serverurl computation (childutils)	; 覆盖serverurl计算(childutils)

三、supervisor的使用

1.supervisord

执行 supervisord 命令,将会启动 supervisord 进程,同时我们在配置文件中设置的进程也会相应启动。

# 使用默认的配置文件 /etc/supervisord.conf
supervisord
# 明确指定配置文件
supervisord -c /etc/supervisor/supervisord.conf
# 使用 user 用户启动 supervisord
supervisord -u user

2.supervisorctl

# 查看supervisor监管的进程状态
supervisorctl status
# 载入最新的配置文件,停止原有进程并按新的配置启动、管理所有进程
supervisorctl reload
# 根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启
supervisorctl update

# 停止某一个进程,program_name 为 [program:x] 里的 x,也就是进程名
supervisorctl stop program_name
# 启动某个进程
supervisorctl start program_name
# 重启某个进程
supervisorctl restart program_name
# 结束所有属于名为 groupworker 这个分组的进程 (start,restart 同理)
supervisorctl stop groupworker:
# 结束 groupworker:name1 这个进程 (start,restart 同理)
supervisorctl stop groupworker:name1
# 停止全部进程,注:start、restart、stop 都不会载入最新的配置文件
supervisorctl stop all

注意:如果我们的stopasgroup和killasgroup设置为flase,我们停止的仅仅是守护进程,不能停止他的子进程,就会发现只是守护进程(父进程停止了),而子进程(程序)还在运行,就会因为端口被占用等原因而无法启动

4.stopsignal、stopasgroup和killasgroup

;进程停止信号,可以为TERM, HUP, INT, QUIT, KILL, USR1, or USR2,默认TERM
;中断:INT(类似于Ctrl+C)(kill -INT pid),退出后会将写文件或日志(推荐)
;终止:TERM(kill -TERM pid) //信号量参考文(http://c.biancheng.net/cpp/html/2784.html)
;挂起:HUP(kill -HUP pid),注意与Ctrl+Z/kill -stop pid不同
;从容停止:QUIT(kill -QUIT pid)
;KILL, USR1, USR2其他见命令(kill -l),说明1
;stopsignal=QUIT               	; signal used to kill process (default TERM)

; 默认为 false,如果设置为 true,当进程收到 stop 信号时,会自动将该信号发给该进程的子进程。
; 如果这个配置项为 true,那么也隐含 killasgroup 为 true。例如在 Debug 模式使用 Flask 时,
; Flask 不会将接收到的 stop 信号也传递给它的子进程,因此就需要设置这个配置项。
stopasgroup=false             ; send stop signal to the UNIX process 

; 默认为 false,如果设置为 true,当进程收到 kill 信号时,会自动将该信号发给该进程的子进程。
; 如果这个程序使用了 python 的 multiprocessing 时,就能自动停止它的子线程。
killasgroup=false             ; SIGKILL the UNIX process group (def false)

另外需要注意command用bash -c 启动 python xx.py一定要设置stopasgroup和killasgroup为true,否则stop不了真正的python/java进程,因为bash命令进程和真正的python进程不是同一个。如果是command=python xx.py这样,并且程序里面没有使用多进程,则无需设置。

4. command 执行多条命令

command = /bin/bash -c "xxx  && xxx"
这样运行是要注意下环境变量问题,比如用python的git包时候,读取不了git的路径居然,最后是在配置的enviroment设置GIT_PYTHON_GIT_EXECUTABLE="/usr/bin/git才解决,但单独运行又能读取git。

 

5.将多个进程按组管理

Supervisor 同时还提供了另外一种进程组的管理方式,通过这种方式,可以使用 supervisorctl 命令来管理一组进程。跟 [program:x] 的进程组不同的是,这里的进程是一个个的 [program:x] 。

[group:thegroupname]
programs=progname1,progname2  ; each refers to 'x' in [program:x] definitions
priority=999                  ; the relative start priority (default 999)

当添加了上述配置后,progname1 和 progname2 的进程名就会变成 thegroupname:progname1 和 thegroupname:progname2 以后就要用这个名字来管理进程了,而不是之前的 progname1 和 progname2。

以后执行 supervisorctl stop thegroupname:就能同时结束 progname1 和 progname2,执行 supervisorctl stop thegroupname:progname1 就能结束 progname1。

 

6.权限问题和异常

设置好配置文件后,应先创建上述配置文件中新增的文件夹。如果指定了启动用户 user,这里以 oxygen 为例,那么应注意相关文件的权限问题,包括日志文件,否则会出现没有权限的错误。例如设置了启动用户 oxygen,然后启动 supervisord 出现错误

Error: Cannot open an HTTP server: socket.error reported errno.EACCES (13)

就是由于上面的配置文件中 /var/run 文件夹,没有授予启动 supervisord 的用户 oxygen 的写权限。/var/run 文件夹实际上是链接到 /run,因此我们修改 /run 的权限。

sudo chmod 777 /run

一般情况下,我们可以用 root 用户启动 supervisord 进程,然后在其所管理的进程中,再具体指定需要以那个用户启动这些进程。

 

报错:gave up: redis entered FATAL state, too many start retries too quickly

一般是因为进程启动太慢造成,在superisor的conf中的[program:xxxx]加入启动时间“startsecs=5”,如果还不行再加大。默认是1秒,重试3次。 

一般守护进程的做法就是fork一个子进程,父进程马上退出,以致于supervisor无法得到子进程的ID。

 

7.使用浏览器来管理

supervisor 同时提供了通过浏览器来管理进程的方法,只需要打开如下几行就可以了。

[inet_http_server]         ; inet (TCP) server disabled by default
port=127.0.0.1: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))

[supervisorctl]
serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
username=user              ; should be same as http_username if set
password=123                ; should be same as http_password if set

注意:实际中发现只设置inet_http_server中的3个,不设置supervisorctl中的3个也是可以的,如果都设置,注意要将ip端口和用户名密码设置的相同,不然会报错

 

8.设置日志级别

loglevel 指定了日志的级别,默认info,其它:debug、warn、trace,用 Python 的 print 语句输出的日志是不会被记录到日志文件中的,需要搭配 Python 的 logging 模块来输出有指定级别的日志。

 

9.多个进程

按照官方文档的定义,一个 [program:x] 实际上是表示一组相同特征或同类的进程组,也就是说一个 [program:x] 可以启动多个进程。这组进程的成员是通过 numprocs 和 process_name 这两个参数来确定。

; 设置进程的名称,使用 supervisorctl 来管理进程时需要使用该进程名
[program:foo] 
; 可以在 command 这里用 python 表达式传递不同的参数给每个进程
command=python server.py --port=90%(process_num)02d
directory=/home/python/tornado_server ; 执行 command 之前,先切换到工作目录
; 若 numprocs 不为1,process_name 的表达式中一定要包含 process_num 来区分不同的进程
numprocs=2                   
process_name=%(program_name)s_%(process_num)02d; 
user=oxygen                 ; 使用 oxygen 用户来启动该进程
autorestart=true            ; 程序崩溃时自动重启
redirect_stderr=true        ; 重定向输出的日志
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

上面这个例子会启动两个进程,process_name 分别为 foo:foo_01 和 foo:foo_02。通过这样一种方式,就可以用一个 [program:x] 配置项,来启动一组非常类似的进程

 

10.开机自动启动 Supervisord

如果是supervisor的配置文件中指定的用户是root,supervisor就会开机自启(原因不清楚),但是我们平时使用的时候并不想用root启动。

Supervisord 默认情况下并没有被安装成服务,它本身也是一个进程。官方已经给出了脚本可以将 Supervisord 安装成服务,可以参考这里查看各种操作系统的安装脚本,但是我用官方这里给的 Ubuntu 脚本却无法运行。

安装方法可以参考 serverfault 上的回答。

Ubuntu 系统,可以这么安装,这里选择了另外一个脚本

# 下载脚本
sudo su - root -c "sudo curl https://gist.githubusercontent.com/howthebodyworks/176149/raw/d60b505a585dda836fadecca8f6b03884153196b/supervisord.sh > /etc/init.d/supervisord"
# 设置该脚本为可以执行
sudo chmod +x /etc/init.d/supervisord
# 设置为开机自动运行
sudo update-rc.d supervisord defaults
# 试一下,是否工作正常
service supervisord stop
service supervisord start

注意:这个脚本下载下来后,还需检查一下与我们的配置是否相符合,比如默认的配置文件路径,pid 文件路径等,如果存在不同则需要进行一些修改。

其实还有一个简单的方法,因为 Linux 在启动的时候会执行 /etc/rc.local 里面的脚本,所以只要在这里添加执行命令就可以

 

注意:在/etc/rc.local脚本下添加开机自启命令

# Ubuntu系统在/etc/rc.local中添加以下内容
# 普通用户没有/var目录的修改权限,会导致supervisord启动不起来,我们需要先修改/var文件的权限
# 不知道为什么我每次修改后一重启就会恢复,所以我把修改权限的命令也放在了这个脚本
# 上面有说到过这个权限问题,这里我比较暴力的改了var下所有文件的权限
chmod 777 /var/*
# 此处要用supervisord的绝对路径,-u指定用户,-c配置文件的绝对路径
# 使用sudo find / -name supervisord查找supervisord的绝对路径
/usr/bin/supervisord -u witcomm -c /etc/supervisor/supervisord.conf
exit 0

以上内容需要添加在 exit 命令前,而且由于在执行 rc.local 脚本时,PATH 环境变量未全部初始化,因此命令需要使用绝对路径。

注意:

         此时supervisor可以以普通用户开机启动了,有的程序也可以正常启动,但是gunicorn无法启动,报错: /bin/bash: gunicorn: 未找到命令,此时我们通过sudo find / -name gunicorn命令查找gunicorn的绝对路径,在supervisor下的配置文件中使用绝对路径即可,如下图

 

未完待续...

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值