English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Supervisor 是基于 Python 的进程管理工具,只能运行在 Unix-Like 的系统上,也就是无法运行在 Windows 上。Supervisor 官方版目前只能运行在 Python 2.4 以上版本,但是还无法运行在 Python 3 上,不过已经有一个 Python 3 的移植版 supervisor-py3k。
什么情况下我们需要进程管理呢?就是执行一些需要以守护进程方式执行的程序,比如一个后台任务,我最常用的是用来启动和管理基于 Tornado 写的 Web 程序。
除此之外,Supervisor 还能很友好的管理程序在命令行上输出的日志,可以将日志重定向到自定义的日志文件中,还能按文件大小对日志进行分割。
Supervisor 有两个主要的组成部分:
安装
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 来执行 restart 和 stop 命令了,将只会得到 unix:///tmp/supervisor.sock 不存在的错误 。
[unix_http_server] ;file=/tmp/supervisor.sock ; (the path to the socket file) ; ändern Sie /var/Verzeichnis 'run', um sicherzustellen, dass es nicht vom System gelöscht wird 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; (Standard ist kein Benutzername (offener Server)) ;password=123 ; (Standard ist kein Passwort (offener Server)) ;[inet_http_server]; inet (TCP)-Server standardmäßig deaktiviert ;port=127.0.0.1:9001 ; (ip_address:Port-Angabe, *:Port für ;alle Interfaces) ;username=user; (Standard ist kein Benutzername (offener Server)) ;password=123 ; (Standard ist kein Passwort (offener Server)) ... [supervisord] ;logfile=/tmp/supervisord.log; (Hauptlogdatei;Standard $CWD/supervisord.log) ; ändern Sie /var/Verzeichnis 'log', um sicherzustellen, dass es nicht vom System gelöscht wird logfile=/var/log/supervisor/supervisord.log; (Hauptlogdatei;Standard $CWD/supervisord.log) logfile_maxbytes=50MB ; (maximale Hauptlogdatei Bytes b4 rotation;Standard 50MB) logfile_backups=10 ; (Anzahl der Sicherungsdateien für die Hauptlogdatei;Standard 10) loglevel=info ; (Log-Stufe;Standard info; andere: debug,warn,trace) ;pidfile=/tmp/supervisord.pid; (supervisord pidfile;Standard supervisord.pid) ; ändern Sie /var/Verzeichnis 'run', um sicherzustellen, dass es nicht vom System gelöscht wird pidfile=/var/run/supervisord.pid; (supervisord pidfile;Standard supervisord.pid) ... ;Setzen Sie den Benutzer, der supervisord startet, normalerweise sollten Sie den Benutzer root nicht leicht verwenden, es sei denn, Sie sind wirklich sicher, dass Sie dies tun möchten ;user=chrism ; (Standard ist der aktuelle Benutzer, erforderlich, wenn root) ... [supervisorctl] ; muss mit der Einstellung von 'unix_http_server' übereinstimmen ;serverurl=unix:///tmp/supervisor.sock; verwenden Sie einen Unix:// URL für einen Unix-Socket ; ändern Sie /var/Verzeichnis 'run', um sicherzustellen, dass es nicht vom System gelöscht wird serverurl=unix:///var/run/supervisor.sock; verwenden Sie einen Unix:// URL für einen Unix-Socket ;serverurl=http://127.0.0.1:9001 ; verwenden Sie http:// URL, um einen inet-Socket anzugeben ;username=chris; sollte gleich http_username sein, wenn gesetzt ;password=123 ; sollte gleich http_password sein, wenn gesetzt ...
In der Standardkonfiguration erreichen die Logdateien des Prozesses5bei 0MB geteilt, wobei maximal10Dateien, natürlich können diese Konfigurationen auch für jeden Prozess einzeln konfiguriert werden.
Berechtigungsproblem
Nachdem die Konfigurationsdatei eingerichtet ist, sollten zuerst die zusätzlichen Verzeichnisse in der Konfigurationsdatei erstellt werden. Wenn der Startbenutzer 'user' angegeben ist, sei 'oxygen' als Beispiel angegeben, dann sollten Sie auf das Berechtigungsproblem der betreffenden Dateien achten, einschließlich der Logdateien, andernfalls können Fehler ohne Berechtigungen auftreten. Zum Beispiel wurde der Benutzer 'oxygen' für den Start eingestellt, und es trat ein Fehler auf, als supervisord gestartet wurde
Fehler: HTTP-Server kann nicht geöffnet werden: socket.error wurde errno.EACCES gemeldet (13)
daher /var/Das Verzeichnis 'run' hat dem Benutzer 'oxygen' keine Schreibrechte zur Aktivierung von supervisord./var/Das Verzeichnis run ist in realtà ein Link zu /run, daher ändern wir /Berechtigungen von run
sudo chmod 777 /run
Das ist etwas einfach und brutal, man könnte auch erwägen, die Dateien .sock, .pid und ähnliche in ein anderes Verzeichnis zu verschieben und sicherzustellen, dass die entsprechenden Berechtigungen vorhanden sind. In der Regel können wir den Prozess supervisord mit dem root-Benutzer starten und dann in den von supervisord verwalteten Prozessen spezifizieren, mit welchem Benutzer diese Prozesse gestartet werden sollen.
Verwenden Sie den Browser zur Verwaltung
Supervisor bietet auch die Möglichkeit, Prozesse über einen Browser zu verwalten, indem einfach die folgenden Zeilen kommentiert werden.
;[inet_http_server]; inet (TCP)-Server standardmäßig deaktiviert ;port=127.0.0.1:9001 ; (ip_address:Port-Angabe, *:Port für ;alle Interfaces) ;username=user; (Standard ist kein Benutzername (offener Server)) ;password=123 ; (Standard ist kein Passwort (offener Server)) [supervisorctl] ... ;serverurl=http://127.0.0.1:9001 ; verwenden Sie http:// URL, um einen inet-Socket anzugeben ;username=chris; sollte gleich http_username sein, wenn gesetzt ;password=123 ; sollte gleich http_password sein, wenn gesetzt
Verwenden Sie include
Am Ende der Konfigurationsdatei befindet sich eine [include]-Konfigurationszeile, ähnlich wie bei Nginx, kann man alle Konfigurationsdateien in einem bestimmten Verzeichnis einbinden. Auf diese Weise können wir die Konfigurationen für jeden Prozess oder einige zusammenhängende Prozesse in einer separaten Datei schreiben.
[include] files = /etc/supervisord.d/*.ini
Konfigurationsbeispiel für Prozesse
Ein einfaches Beispiel ist wie folgt
; Definition des Prozessnamens, dieser Name wird benötigt, um den Prozess mit supervisorctl zu verwalten [program:your_program_name] command=python server.py --port=9000 ; numprocs=1 ; standardwert für1 ;process_name=%(program_name)s; standardwert für %(program_name)s, d.h. [program:x] mit x directory=/home/python/tornado_server; Wechsel in das Arbeitsverzeichnis vor der Ausführung des Befehls user=oxygen; Den Prozess mit dem Benutzer oxygen starten ; Bei Absturz des Programms automatisch neu starten, die Anzahl der Neustarts ist begrenzt, Standardwert}3mal autorestart=true redirect_stderr=true; Weiterleitung der Ausgabelogdateien stdout_logfile = /var/log/supervisord/tornado_server.log loglevel=info
Log-Stufe einstellen
loglevel gibt die Stufe der Protokollierung an. Die Protokollierung, die mit Python-Print-Befehlen ausgegeben wird, wird nicht in die Logdatei eingetragen. Es ist erforderlich, den logging-Modul von Python zu verwenden, um Protokollierungen mit einer bestimmten Stufe auszugeben.
Mehrere Prozesse
Laut der Definition in der offiziellen Dokumentation stellt ein [program:x] eine Gruppe von Prozessen mit gleichen Eigenschaften oder derselben Kategorie dar, das bedeutet, dass ein [program:x] mehrere Prozesse starten kann. Diese Gruppe von Prozessen wird durch die Parameter numprocs und process_name bestimmt. Was bedeutet das? Lassen Sie uns einen Beispielcode betrachten.
; Definition des Prozessnamens, dieser Name wird benötigt, um den Prozess mit supervisorctl zu verwalten [program:foo] ; Es können hier Python-Ausdrücke verwendet werden, um verschiedenen Prozessen verschiedene Parameter zu übergeben command=python server.py --port=90%(process_num)02d directory=/home/python/tornado_server; Wechsel in das Arbeitsverzeichnis vor der Ausführung des Befehls ; Wenn numprocs nicht1Die Ausdrucksformel von process_name muss unbedingt process_num enthalten, um verschiedene Prozesse zu unterscheiden numprocs=2 process_name=%(program_name)s_%(process_num)02d; user=oxygen; Den Prozess mit dem Benutzer oxygen starten autorestart=true; Bei Absturz des Programms automatisch neu starten redirect_stderr=true; Weiterleitung der Ausgabelogdateien stdout_logfile = /var/log/supervisord/tornado_server.log loglevel=info
Dieser Beispielcode startet zwei Prozesse, deren process_name foo:foo_0 sind1 und foo:foo_02Auf diese Weise kann man mit einem [program:x] -Konfigurationsparameter eine Gruppe sehr ähnlicher Prozesse starten.
Ich stelle noch zwei Konfigurationsoptionen vor stopasgroup und killasgroup
; Standard ist false, wenn auf true gesetzt, wird das Stop-Signal automatisch an die Unterprozesse des Prozesses gesendet. Wenn dieser Eintrag auf true gesetzt ist, wird auch killasgroup auf true gesetzt. Zum Beispiel bei der Verwendung von Flask im Debug-Modus wird Flask das empfangene Stop-Signal nicht an seine Unterprozesse weiterleiten, daher muss dieser Eintrag gesetzt werden.
stopasgroup=false ; sende Stop-Signal an den UNIX-Prozess ; Standard ist false, wenn auf true gesetzt, wird der Signal kill automatisch an die Unterprozesse des Prozesses gesendet. Wenn dieses Programm python multiprocessing verwendet, kann es automatisch die Unterprozesse beenden. killasgroup=false ; SIGKILL den UNIX-Prozessgruppe (Standard: false)
Eine detailliertere Konfigurationsbeispiel kann wie folgt referenziert werden, die offizielle Dokumentation ist hier
;[program:theprogramname] ; command=/bin/cat ; das Programm (relative verwendet PATH, kann Argumente akzeptieren) ; process_name=%(program_name)s ; Ausdrucksformel für process_name (Standardwert %(program_name)s) ; numprocs=1 ; Anzahl der Prozesskopien, die gestartet werden sollen (Standard 1) ; directory=/tmp ; Verzeichnis, in das vor der Ausführung cd wird (Standard: kein cwd) ; umask=022 ; umask für den Prozess (Standard: None) ; priority=999 ; die relative Startpriorität (Standard) 999) ; autostart=true ; beim Start von supervisord starten (Standard: true) ; autorestart=unerwartet ; ob/Wann neu starten soll (Standard: unerwartet) ; startsecs=1 ; Anzahl der Sekunden, die das Programm laufen muss (Standardwert) 1) ;startretries=3 ; maximale Anzahl von Serienstartfehlern (Vorgabe 3) ;exitcodes=0,2 ; 'erwartete' Ausgabecodes für den Prozess (Vorgabe 0,2) ;stopsignal=QUIT ; Signal, das zum Beenden des Prozesses verwendet wird (Vorgabe TERM) ;stopwaitsecs=10 ; maximale Anzahl von Sekunden, um zu warten b4 SIGKILL (Vorgabe 10) ;stopasgroup=false ; Senden Sie das Stop-Signal an die UNIX-Prozessgruppe (Vorgabe false) ;killasgroup=false ; SIGKILL den UNIX-Prozessgruppe (Vorgabe false) ;user=chrism ; Setze setuid auf dieses UNIX-Konto, um das Programm auszuführen ;redirect_stderr=true ; Leite proc stderr zu stdout um (Vorgabe false) ;stdout_logfile=/a/Pfad ; Pfad für stdout-Log, NONE für keins; Vorgabe AUTO ;stdout_logfile_maxbytes=1MB ; maximale Anzahl von Bytes im Protokolldatei-Log (max # logfile bytes b)4 rotation (Vorgabe) 50MB) ;stdout_logfile_backups=10 ; # der Protokolldatei-Sicherungen für stdout (Vorgabe 10) ;stdout_capture_maxbytes=1MB ; Anzahl der Bytes in 'capturemode' (Standard 0) ;stdout_events_enabled=false ; Emitte Ereignisse bei stdout-Schreibvorgängen (Vorgabe false) ;stderr_logfile=/a/Pfad ; Pfad für stderr-Log, NONE für keins; Vorgabe AUTO ;stderr_logfile_maxbytes=1MB ; maximale Anzahl von Bytes im Protokolldatei-Log (max # logfile bytes b)4 rotation (Vorgabe) 50MB) ;stderr_logfile_backups=10 ; # von stderr logfile backups (Standard 10) ;stderr_capture_maxbytes=1MB ; Anzahl der Bytes in 'capturemode' (Standard 0) ;stderr_events_enabled=false ; emite Ereignisse auf stderr Schreibvorgänge (Standard false) ;environment=A="1",B="2" ; process environment additions (def no adds) ;serverurl=AUTO ; überschreibe serverurl Berechnung (childutils)
Mehrere Prozesse können gruppenweise verwaltet werden
Supervisor bietet auch eine andere Art der Verwaltung von Prozessgruppen an. Auf diese Weise können Sie mit dem Befehl supervisorctl eine Gruppe von Prozessen verwalten. Im Gegensatz zur Prozessgruppe [program:x] sind hier die Prozesse einzeln [program:x].
[group:thegroupname] programs=progname1,progname2 ; jede bezieht sich auf 'x' in [program:x] Definitionen ; priority=999 ; die relative Startpriorität (Standard) 999)
Wenn Sie die obige Konfiguration hinzufügen, wird progname1 und progname2 der Prozessname wird thegroupname:progname1 und thegroupname:progname2 Ab dann müssen Sie diesen Namen verwenden, um Prozesse zu verwalten, anstatt des vorherigen progname1。
Ab dann können Sie mit supervisorctl stop thegroupname: progname gleichzeitig progname beenden1 und progname2,führen Sie supervisorctl stop thegroupname:progname aus1 kann progname beendet werden1。supervisorctl-Befehle werden wir später einführen。
Starten Sie supervisord
Durch Ausführen des Befehls supervisord wird der supervisord-Prozess gestartet, und gleichzeitig werden die Prozesse, die wir in der Konfigurationsdatei eingerichtet haben, ebenfalls entsprechend gestartet.
# 使用默认的配置文件 /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 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中的脚本,所以只要在这里添加执行命令就可以
# 如果是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
声明:本文内容来自网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#oldtoolbag.com(在发送邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立即删除涉嫌侵权内容。