メモ > サーバ > 各論: エトセトラ > バックグラウンドで処理を実行する(Supervisor)
バックグラウンドで処理を実行する(Supervisor)
Supervisor を実際に操作してデーモン化に触れてみる
https://www.ritolab.com/entry/224
Supervisorの基本コマンド - Qiita
https://qiita.com/mokkos/items/473978ef0699df3173f5
Supervisorは、プロセスを監視して落ちたら起動しなおしてくれたりするツール(つまりデーモン化できる)
Supervisorを起動すると、設定している管理対象も一緒に起動してくれる
「無限ループで処理するプログラムをバックグラウンドで実行しておけばいいが、落ちた場合の対処を考えたい」のような場合に有効そう
(systemdでも同じことは実現できるが、Supervisorだと「root権限で無くても起動や停止ができる」などのメリットがあり、手軽に利用できるようになる)
EC2のAmazon Linux 2にSupervisorを導入する - Breath Note
https://blog.shinki.net/posts/amazon-ilnux-2-supervisor
Amazon Linux 2にSupervisorを設定する - ハマログ
https://blog.e2info.co.jp/2021/04/11/amazon-linux-2_supervisor/
Supervisor入門(AmazonLinux2 + Supervisor4系) インストールからハマったポイント|スクショはつらいよ
https://chariosan.com/2019/11/10/supervisor4_al2/
Amazonlinux2でsupervisorを動かすまで - zuntan02のはてなブログ
https://zuntan02.hateblo.jp/entry/2019/06/27/205849
amazon linuxにsupervisorを入れたメモ - Qiita
https://qiita.com/abouch/items/3f4b422c7d9048936629
Supervisorの使用方法 - TASK NOTES
https://www.task-notes.com/entry/20170311/1489224418
SupervisorでLaravelのQueue worker管理 | ソフトウェア開発のギークフィード
https://www.geekfeed.co.jp/geekblog/laravel_queue_with_supervisor/
■準備
下準備として以下を実行しておいたが、今回の検証では恐らく無くても大丈夫
# localectl set-locale LANG=ja_JP.UTF-8
# localectl status
# timedatectl set-timezone Asia/Tokyo
# timedatectl status
# yum -y install httpd
# vi /etc/httpd/conf/httpd.conf
# service httpd start
# chkconfig httpd on
# yum -y install php php-mbstring php-gd
■インストール
CentOS7の場合、yumでインストールする
# yum install supervisor
# curl -o /etc/rc.d/init.d/supervisord https://raw.githubusercontent.com/Supervisor/initscripts/master/redhat-init-equeffelec
# chmod 755 /etc/rc.d/init.d/supervisord
Amazon Linux 2 の場合、yumではインストールできない
以下のようにpip経由でインストールする
# pip3 -V
pip 20.2.2 from /usr/lib/python3.7/site-packages/pip (python 3.7)
# pip3 install supervisor
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
Collecting supervisor
Downloading supervisor-4.2.2-py2.py3-none-any.whl (743 kB)
|■■■■■■■■■■■■■■■■| 743 kB 23.2 MB/s
Installing collected packages: supervisor
Successfully installed supervisor-4.2.2
# supervisord -v
4.2.2
なお Amazon Linux 2 でも、起動した時期によってはpip3が使えない
その場合は先にpip3をインストールする
AmazonLinux2でPython3環境構築 - Qiita
https://qiita.com/hiren/items/17984191da2ab8955174
$ python -V
Python 2.7.18
$ pip --version
-bash: pip: コマンドが見つかりません
$ pipenv --version
-bash: pipenv: コマンドが見つかりません
$ sudo yum install -y python3
$ python3 -V
Python 3.7.10
$ pip3 --version
pip 20.2.2 from /usr/lib/python3.7/site-packages/pip (python 3.7)
■設定
以下はAmazon Linux 2の場合に作業する(CentOS7の手順でインストールした場合、作成済みになっている)
# mkdir /etc/supervisord.d
# mkdir /var/log/supervisor
# vi /etc/logrotate.d/supervisor
ログローテートについては、Basis.txt の「ログ保存期間を設定」も参照
以降はCentOS7とAmazon Linux 2のどちらの場合も必要な作業
ただしCentOS7の場合、3箇所ある /usr/local/bin という箇所を /usr/bin にする(supervisord がここに置かれているため)
/var/log/supervisor/*.log {
missingok
weekly
notifempty
nocompress
}
# echo_supervisord_conf > /etc/supervisord.conf
# cp -p /etc/supervisord.conf /etc/supervisord.conf.org
# vi /etc/supervisord.conf
■起動と確認
設定が終わったら起動する
;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile=/var/log/supervisor/supervisord.log
;pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
pidfile=/var/run/supervisord.pid
;[include]
;files = relative/directory/*.ini
[include]
files = supervisord.d/*.ini
# vi /etc/systemd/system/supervisord.service
[Unit]
Description=Supervisor process control system for UNIX
Documentation=http://supervisord.org
After=network.target
[Service]
ExecStart=/usr/local/bin/supervisord -n -c /etc/supervisord.conf
ExecStop=/usr/local/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/local/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=50s
[Install]
WantedBy=multi-user.target
# systemctl start supervisord
# systemctl status supervisord
● supervisord.service - Supervisor process control system for UNIX
Loaded: loaded (/etc/systemd/system/supervisord.service; disabled; vendor preset: disabled)
Active: active (running) since 木 2021-12-23 15:38:20 JST; 2s ago
Docs: http://supervisord.org
Main PID: 453 (supervisord)
CGroup: /system.slice/supervisord.service
└─453 /usr/bin/python3 /usr/local/bin/supervisord -n -c /etc/supervisord.conf
12月 23 15:38:20 ip-10-1-0-201.ap-northeast-1.compute.internal systemd[1]: supervisord.service holdoff time over, scheduling restart.
12月 23 15:38:20 ip-10-1-0-201.ap-northeast-1.compute.internal systemd[1]: Stopped Supervisor process control system for UNIX.
12月 23 15:38:20 ip-10-1-0-201.ap-northeast-1.compute.internal systemd[1]: Started Supervisor process control system for UNIX.
12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,080 CRIT Supervisor is running as root...age.
12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,081 WARN No file matches via include "...ini"
12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,086 INFO RPC interface 'supervisor' in...ized
12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,086 CRIT Server 'unix_http_server' run...king
12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,086 INFO supervisord started with pid 453
Hint: Some lines were ellipsized, use -l to show in full.
プログラムのデーモン化を試す
CentOS7の場合、「ec2-user」というユーザ名では無いので、適宜調整する
# vi /home/ec2-user/hello.sh
以下でログが出力され続けていることを確認できる
#!/bin/sh
while true
do
sleep 5s
echo "hello "`date`
done
# vi /etc/supervisord.d/hello.ini
[program:hello]
directory=/home/ec2-user
command=/bin/sh hello.sh
user=root
autostart=true
autorestart=true
stdout_logfile=/home/ec2-user/hello.log
redirect_stderr=true
# systemctl restart supervisord
# systemctl status supervisord
# tail -f /home/ec2-user/hello.log
以下で管理対象になっていることが確認できる
# supervisorctl status
hello RUNNING pid 4395, uptime 0:00:06
以下のようにプロセスを強制終了させても、すぐに新しく起動されることが確認できる
# ps aux | grep hello
root 4395 0.0 0.0 115412 1492 ? S 15:07 0:00 /bin/sh hello.sh
root 4463 0.0 0.0 112812 972 pts/0 R+ 15:09 0:00 grep --color=auto hello
# kill 4395
# ps aux | grep hello
root 4466 0.0 0.0 115408 1448 ? S 15:09 0:00 /bin/sh hello.sh
root 4469 0.0 0.0 112812 976 pts/0 S+ 15:09 0:00 grep --color=auto hello
また、/etc/supervisord.d/hello.ini を削除してから supervisord を再起動すると、上記のプロセスは現れなくなる
■挙動の確認
以下で停止と再開ができる
ini ファイルで autostart と autorestart が true に設定されている場合、「systemctl restart supervisord」によって自動的に起動される
# supervisorctl status
hello RUNNING pid 4682, uptime 0:00:18
# supervisorctl stop hello
hello: stopped
# supervisorctl status
hello STOPPED Dec 28 03:24 PM
# supervisorctl start hello
hello: started
# supervisorctl status
hello RUNNING pid 4698, uptime 0:00:02
以下で管理対象からの除外と再追加ができる
ini ファイルで autostart と autorestart が true に設定されていても、「systemctl restart supervisord」によって自動的に起動されない
# supervisorctl status
hello STOPPED Dec 28 03:27 PM
# supervisorctl stop hello
hello: stopped
# supervisorctl remove hello
hello: removed process group
# supervisorctl status
# supervisorctl add hello
hello: added process group
# supervisorctl status
hello RUNNING pid 4765, uptime 0:00:08
■トラブル: インストール時にエラー
CentOS7の場合はyumでインストールできるようだが、Amazon Linux 2の場合はインストールできなかった
上記のとおり、pipでインストールできた
# yum install supervisor
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
パッケージ supervisor は利用できません。
エラー: 何もしません
■トラブル: 起動時にエラー
色々なページの解説どおりに進めても、以下のエラーになって起動できなかった
エラーの例
# systemctl start supervisord
# systemctl status supervisord
● supervisord.service - Supervisor process control system for UNIX
Loaded: loaded (/etc/systemd/system/supervisord.service; disabled; vendor preset: disabled)
Active: activating (auto-restart) (Result: exit-code) since 木 2021-12-23 15:26:18 JST; 17s ago
Docs: http://supervisord.org
Process: 32763 ExecStart=/usr/bin/supervisord -n -c /etc/supervisord.conf (code=exited, status=203/EXEC)
Main PID: 32763 (code=exited, status=203/EXEC)
12月 23 15:26:18 ip-10-1-0-201.ap-northeast-1.compute.internal systemd[1]: supervisord.service failed.
/var/log/messages を確認すると、以下のエラーになっていた
Dec 23 06:32:09 ip-10-1-0-201 systemd: Started Supervisor process control system for UNIX.
Dec 23 06:32:09 ip-10-1-0-201 systemd: Failed at step EXEC spawning /usr/bin/supervisord: No such file or directory
Dec 23 06:32:09 ip-10-1-0-201 systemd: supervisord.service: main process exited, code=exited, status=203/EXEC
Dec 23 06:32:09 ip-10-1-0-201 systemd: Unit supervisord.service entered failed state.
Dec 23 06:32:09 ip-10-1-0-201 systemd: supervisord.service failed.
「/usr/bin/supervisord が存在しない」となっている
/usr/bin のパスを /usr/local/bin に修正すると起動できた(インストール方法によっては、ファイルの場所が異なるみたい)
# systemctl daemon-reload
# systemctl start supervisord
# systemctl status supervisord
なお「systemctl daemon-reload」はキャッシュクリアのようなものだと思われる
systemctl daemon-reload って何 - Qiita
https://qiita.com/taro-hida/items/ec187c0fae893177e575
■トラブル: supervisorctlコマンドを使用できない
いつの間にかsupervisorctlコマンドが使えなくなっていたので、対応したときのメモ
supervisordを再起動する
$ sudo /usr/local/bin/supervisorctl version
unix:///tmp/supervisor.sock no such file
$ sudo service supervisord restart
$ sudo /usr/local/bin/supervisorctl version
4.2.5
ec2-userで .bash_profile の最終行に設定を追加
$ vi .bash_profile
$ source ~/.bash_profile
追加した内容は以下のとおり
alias sudo='sudo env PATH=$PATH'
以下のとおり、呼び出せるようになった
$ sudo supervisorctl status
artisan-queue:artisan-queue_00 RUNNING pid 28312, uptime 0:02:34
artisan-schedule:artisan-schedule_00 RUNNING pid 28313, uptime 0:02:34