概要
Webサービスを運営していると、夜中にWebサーバーのプロセスが突然死してしまい、朝に気づくということが多々あります。
流石に人間が24時間365日監視しているのはツラいので、ある特定のプロセスが落ちたら自動で検知と再起動
という処理を行いたいです。
今回はSnapmartのWebサーバーにmonitを導入してunicornを不死鳥にしたので、その導入について書きます。
monitとは
冒頭でも述べましたが、ざっくりいうとmonitはサーバーのある特定のプロセスを監視し、プロセスがなくなったことを検知、自動再起動を行うOSSです。 monitが監視する条件に合致した場合に再起動を行うだけなので、原因の根本解決などは人間が行う必要があります。
導入手順
手順は大きく4つあります。
- monitをinstall
- unicornの起動スクリプトを書く
- unicorn用のmonitの設定を記述
- monitの再起動と動作確認
monitをinstall
monitはyumでinstallすることができます。
sudo yum install monit
unicornの起動スクリプトを書く
monitが自動で再起動させるためのスクリプトを書きます。
このスクリプトは/etc/init.d/unicorn
に配置します。
スクリプトの内容は下記の通りです。
#!/bin/sh NAME="Unicorn" ENV=production RAILS_DIR="/awesome_your_app" PID="${RAILS_DIR}/log/unicorn/unicorn.pid" CONF="${RAILS_DIR}/config/unicorn.rb" start() { if [ -e $PID ]; then echo "already started" exit 1 fi echo "start unicorn" su - ec2-user -c "cd ${RAILS_DIR} && bundle exec unicorn_rails -c ${CONF} -E ${ENV} -D" } stop() { if [ ! -e $PID ]; then echo "${NAME} already stopped" exit 1 fi echo "stop ${NAME}" kill -QUIT `cat ${PID}` } restart() { stop sleep 3 start } case "$1" in start) start ;; stop) stop ;; restart) restart ;; *) echo "Syntax Error" exit 2 ;; esac
上記のファイルを作成すると、/etc/init.d/unicorn start|stop|restart
を行うことができます。
これを用いてmonitがプロセスの再起動を行うわけです。
※併せてchkconfig
を設定するのも良いと思います。今回は割愛
unicorn用のmonitの設定を記述
monit.conf
まずmonit自体の設定を行います。設定ファイルは/etc/monit.conf
です。
こちらのファイルで重要なのは、Include /etc/monit.d/*.monitrcです。
これは、/etc/monit.d/
配下にある*.monitrc
をIncludeする設定です。この設定を行い、特定のモジュールに限定した設定ファイルを用意することで、管理が容易になります。
set daemon 60 set mailserver localhost set eventqueue basedir /var/monit slots 100 set logfile syslog Include /etc/monit.d/*.monitrc Include /etc/monit.d/logging set httpd port 2812 and use the address localhost allow localhost
/etc/monit.d/unicorn.monitrc
続いて、monitのunicorn監視用の設定を書いていきます。
check process unicorn with pidfile /awesome_your_app/log/unicorn/unicorn.pid group ec2-user start program = "/etc/init.d/unicorn restart" stop program = "/etc/init.d/unicorn stop" if 5 restarts within 5 cycles then unmonitor
設定はとてもシンプルです。
- start, stopをどのgroupで、どのコマンドを実行するか
- 何サイクルで何度失敗したら監視をやめるかを設定しています。
monitの再起動と動作確認
monitの再起動
これまでの設定を再読み込みしたいので、monitを再起動します。
sudo monit reload
動作確認
最後に動作確認をします。
- monitがunicornプロセスを監視しているのか
- unicornプロセスが落ちた場合に自動で再起動するか
上記2点が満たされれば良しとします。
monitがunicornプロセスを監視しているのか
monitの状況はsudo monit status
コマンドで確認できます。
Process 'unicorn' status running monitoring status monitored pid 3941 parent pid 1 uptime 5h 0m children 5 memory kilobytes 204080 memory kilobytes total 1670284 memory percent 5.3% memory percent total 44.0% cpu percent 0.0% cpu percent total 0.0% data collected Thu May 23 04:08:47 2019
バッチリですね!
unicornプロセスが落ちた場合に自動で再起動するか
monitのログを確認するために、sudo tail -f /var/log/monit
でログを見守ります。
別のプロセスで/etc/init.d/unicorn stop
を行います。
[UTC May 23 00:59:41] error : 'unicorn' process is not running [UTC May 23 00:59:41] info : 'unicorn' trying to restart [UTC May 23 00:59:41] info : 'unicorn' start: /etc/init.d/unicorn [UTC May 23 01:00:42] info : 'unicorn' process is running with pid 20241
1分ほどすると上記のようにログが出てきます。
- unicorn プロセスが実行されていないことを検知
- unicorn プロセスを起動させようと試みる
- /etc/init.d/unicornを実行
- PID: 20241でunicornが起動
といった具合で自動で起動されました。バッチリですね!
まとめ
今回は、monitを導入してunicornプロセスが落ちた場合に自動で再起動されるようにしました。
unicornだけではなく、nginxやpostfixといったミドルウェアが謎の変死を遂げるのであれば、monitの導入を考えても良いでしょう。
また、monitを導入すると、導入の背景にあった人間が24時間365日監視を行うということから解放されます。
心配が一つ減るのは良いですね。
ただ、monitで再起動がかかるのは良いのですが、根本の原因は解決しなければなりません。
運用の負担はどんどん減らしていきましょう。