>  기사  >  백엔드 개발  >  Python 기반 프로세스 관리 도구 감독자 사용 가이드

Python 기반 프로세스 관리 도구 감독자 사용 가이드

高洛峰
高洛峰원래의
2017-02-22 17:00:331382검색

Supervisor는 Python 기반의 프로세스 관리 도구로, 데몬 프로세스로 실행해야 하는 일부 프로그램, 즉 백그라운드 작업을 쉽게 관리할 수 있습니다. 예를 들어 Tornado 기반으로 작성된 웹 프로그램을 시작하고 관리하는 데 사용됩니다. .

Supervisor는 Unix 계열 시스템에서만 실행할 수 있는 Python 기반 프로세스 관리 도구입니다. 즉, Windows에서는 실행할 수 없습니다. Supervisor의 공식 버전은 현재 Python 2.4 이상에서만 실행될 수 있지만 아직 Python 3에서는 실행할 수 없습니다. 그러나 이미 Python 3 포팅 ​​버전 Supervisor-py3k가 있습니다.

어떤 상황에서 프로세스 관리가 필요한가요? 백그라운드 작업 등 데몬 프로세스로 실행해야 하는 일부 프로그램을 실행하는 것입니다. Tornado를 기반으로 작성된 웹 프로그램을 시작하고 관리하는 데 가장 많이 사용됩니다.

또한 Supervisor는 명령줄에서 프로그램의 로그 출력을 매우 친절하게 관리하고, 로그를 사용자 정의 로그 파일로 리디렉션하고, 파일 크기에 따라 로그를 분할할 수 있습니다.

Supervisor에는

  1. supervisor라는 두 가지 주요 구성 요소가 있습니다. Supervisor를 실행하면 관리되는 프로세스를 시작하고 프로세스를 관리하는 프로세스 감독자가 시작됩니다. 프로세스는 자체 하위 프로세스로 시작되며 관리되는 프로세스가 충돌할 때 자동으로 다시 시작될 수 있습니다.

  2. supervisorctl은 중지, 시작, 다시 시작 등의 명령을 실행하여 이러한 하위 프로세스를 관리하는 데 사용할 수 있는 명령줄 관리 도구입니다.

설치

sudo pip install supervisor

구성 파일 생성

echo_supervisord_conf > /etc/supervisord.conf

허가 없이 문제가 있는 경우 이 명령을 사용하면 됩니다.

sudo su - root -c "echo_supervisord_conf > /etc/supervisord .conf"

구성 파일 설명

관리해야 하는 프로세스를 구성하는 방법을 알고 싶다면 Supervisord.conf를 열면 됩니다. 매우 자세한 정보가 있습니다.

구성 파일 열기

vim /etc/supervisord.conf

기본 구성 파일은 다음과 같으나, 꼭 필요한 함정이 있습니다. Supervisord.pid 및 Supervisor.sock은 /tmp 디렉토리에 있지만 /tmp 디렉토리는 임시 파일을 저장하며, 내부 파일은 Linux 시스템에 의해 삭제됩니다. 이러한 파일이 손실되면 다시 시작하고 중지하십시오. supervisorctl.명령을 통해 실행할 수 없으면 unix:///tmp/supervisor.sock이 존재하지 않는다는 오류만 발생합니다.

[unix_http_server]
;file=/tmp/supervisor.sock  ; (the path to the socket file)
;修改为 /var/run 目录,避免被系统删除
file=/var/run/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))

;[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))
...

[supervisord]
;logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
;修改为 /var/log 目录,避免被系统删除
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB    ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10      ; (num of main logfile rotation backups;default 10)
loglevel=info        ; (log level;default info; others: debug,warn,trace)
;pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
;修改为 /var/run 目录,避免被系统删除
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
...
;设置启动supervisord的用户,一般情况下不要轻易用root用户来启动,除非你真的确定要这么做
;user=chrism         ; (default is current user, required if root)
...

[supervisorctl]
; 必须和'unix_http_server'里面的设定匹配
;serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
;修改为 /var/run 目录,避免被系统删除
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://www.php.cn/:9001 ; use an http:// url to specify an inet socket
;username=chris       ; should be same as http_username if set
;password=123        ; should be same as http_password if set
...

기본적으로 프로세스의 로그 파일이 50MB에 도달하면 분할되어 최대 10개의 파일이 유지됩니다. 각 프로세스에 대해 구성을 개별적으로 구성할 수도 있습니다.

권한 문제

구성 파일 설정 후 먼저 위 구성 파일에 새 폴더를 생성해야 합니다. 시작 사용자 user가 지정된 경우 여기서는 산소를 예로 들어 로그 파일을 포함한 관련 파일의 권한에 주의해야 합니다. 그렇지 않으면 권한이 없는 오류가 발생합니다. 예를 들어, 시작 사용자 산소를 설정한 후 Supervisord를 시작하면 오류가 발생합니다.

오류: HTTP 서버를 열 수 없습니다: 소켓.오류가 errno.EACCES (13)

위 구성 파일의 /var/run 폴더가 Supervisord를 시작한 사용자 산소에게 쓰기 권한을 부여하지 않기 때문입니다. /var/run 폴더는 실제로 /run에 연결되어 있으므로 /run의 권한을 수정합니다.

sudo chmod 777 /run

조금 단순하고 투박한 내용이지만 위 구성 파일의 .sock, .pid 및 기타 파일을 다른 폴더로 수정하는 것도 고려해 볼 수 있습니다. 해당 권한이 충분한지 확인하세요. 일반적인 상황에서는 루트 사용자를 사용하여 감독자 프로세스를 시작한 다음 관리하는 프로세스에서 이러한 프로세스를 시작해야 하는 사용자를 지정할 수 있습니다.

브라우저를 사용하여 관리

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://www.php.cn/:9001 ; use an http:// url to specify an inet socket
;username=chris       ; should be same as http_username if set
;password=123        ; should be same as http_password if set

基于Python 的进程管理工具supervisor使用指南

include 사용

구성 파일 끝에서, Nginx와 같은 [include] 구성 항목은 특정 폴더의 모든 구성 파일을 포함할 수 있으므로 각 프로세스 또는 여러 관련 프로세스의 구성에 대해 별도의 파일을 작성할 수 있습니다.

[include]
files = /etc/supervisord.d/*.ini

프로세스 구성 예시

간단한 예시는 다음과 같습니다

; 设置进程的名称,使用 supervisorctl 来管理进程时需要使用该进程名
[program:your_program_name] 
command=python server.py --port=9000
;numprocs=1         ; 默认为1
;process_name=%(program_name)s  ; 默认为 %(program_name)s,即 [program:x] 中的 x
directory=/home/python/tornado_server ; 执行 command 之前,先切换到工作目录
user=oxygen         ; 使用 oxygen 用户来启动该进程
; 程序崩溃时自动重启,重启次数是有限制的,默认为3次
autorestart=true      
redirect_stderr=true    ; 重定向输出的日志
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

로그 수준 설정

loglevel은 로그 수준을 지정합니다. Python의 print 문을 사용한 로그 출력은 로그 파일에 기록되지 않습니다. Python의 로깅 모듈과 결합하여 지정된 수준의 로그를 출력합니다.

다중 프로세스

按照官方文档的定义,一个 [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] 配置项,来启动一组非常类似的进程。

再介绍两个配置项 stopasgroup 和 killasgroup

; 默认为 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)

更详细的配置例子,可以参考如下,官方文档在这里

;[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)
;autorestart=unexpected    ; whether/when to restart (default: unexpected)
;startsecs=1          ; number of secs prog must stay running (def. 1)
;startretries=3        ; max # of serial start failures (default 3)
;exitcodes=0,2         ; 'expected' exit codes for process (default 0,2)
;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 (default 10)
;stdout_capture_maxbytes=1MB  ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false  ; emit events on stdout writes (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 (default 10)
;stderr_capture_maxbytes=1MB  ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false  ; emit events on stderr writes (default false)
;environment=A="1",B="2"    ; process environment additions (def no adds)
;serverurl=AUTO        ; override serverurl computation (childutils)

将多个进程按组管理

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。

以后执行 supervisorctl stop thegroupname: 就能同时结束 progname1 和 progname2,执行 supervisorctl stop thegroupname:progname1 就能结束 progname1。supervisorctl 的命令我们稍后介绍。

启动 supervisord

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

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

更多参数请参考文档

supervisorctl 命令介绍

# 停止某一个进程,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
# 载入最新的配置文件,停止原有进程并按新的配置启动、管理所有进程
supervisorctl reload
# 根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启
supervisorctl update

注意:显示用 stop 停止掉的进程,用 reload 或者 update 都不会自动重启。也可以参考这里

开机自动启动 Supervisord

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

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

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

# 下载脚本
sudo su - root -c "sudo curl http://www.php.cn/ > /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 里面的脚本,所以只要在这里添加执行命令就可以

# 如果是 Ubuntu 添加以下内容
/usr/local/bin/supervisord -c /etc/supervisord.conf

# 如果是 Centos 添加以下内容
/usr/bin/supervisord -c /etc/supervisord.conf

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

在添加前,先在终端测试一下命令是否能正常执行,如果找不到 supervisord,可以用如下命令找到

sudo find / -name supervisord


更多基于Python 的进程管理工具supervisor使用指南相关文章请关注PHP中文网!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.