supervisorはプログラムの起動監視と、自動起動/復帰などを行ってくれるツールです。
これをつかってSQSの受信処理プログラムをワーカーとして管理してみます。
受信テスト用のスクリプトを作成
メッセージの受信は、一度に最大の10件まで、ポーリング20秒で受信したメッセージをログファイルに出力するようにします。
また、今回はログの出力タイミングがわかりやすいように、1回のポーリング後10秒間sleepしています。
$ vim /home/ec2-user/svsqs.rb
#!/usr/local/bin/ruby require 'aws-sdk' require 'logger' access_key = 'XXXXXXXXXXXXXXXX' secret_key = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY' queue_url = 'https://sqs.ap-northeast-1.amazonaws.com/ZZZZZZZZZZZ/svsqs' log = Logger.new("/home/ec2-user/test.log"); AWS.config(:access_key_id => access_key, :secret_access_key => secret_key, :region => "ap-northeast-1") sqs = AWS::SQS.new while true messages = sqs.queues[queue_url].receive_message({:limit => 10, :wait_time_seconds => 20}).map do |m| json = JSON.parse(m.body) log.debug("#{$$} #{json['msg']}") m.delete() end log.debug("#{$$} -------") sleep 10 end
$ chmod 755 /home/ec2-user/svsqs.rb
supervisorのインストールと設定
次に、supervisorをインストールして、上記のスクリプトの起動管理するように設定します。
# easy_install supervisor # vim /etc/init.d/supervisord
次にsupervisor自体の起動スクリプトをつくってサービス登録します。
#!/bin/sh # # /etc/rc.d/init.d/supervisord # # Supervisor is a client/server system that # allows its users to monitor and control a # number of processes on UNIX-like operating # systems. # # chkconfig: - 64 36 # description: Supervisor Server # processname: supervisord # Source init functions . /etc/init.d/functions RETVAL=0 prog="supervisord" pidfile="/tmp/supervisord.pid" lockfile="/var/lock/subsys/supervisord" start() { echo -n $"Starting $prog: " daemon --pidfile $pidfile supervisord RETVAL=$? echo [ $RETVAL -eq 0 ] && touch ${lockfile} } stop() { echo -n $"Shutting down $prog: " killproc -p ${pidfile} /usr/bin/supervisord RETVAL=$? echo if [ $RETVAL -eq 0 ] ; then rm -f ${lockfile} ${pidfile} fi } case "$1" in start) start ;; stop) stop ;; status) status $prog ;; restart) stop start ;; *) echo "Usage: $0 {start|stop|restart|status}" ;; esac
# chmod 755 /etc/init.d/supervisord # chkconfig --add supervisord # chkconfig supervisord on # chkconfig --list
監視対象プロセスの設定
子設定ファイルの読込み設定
主設定ファイルの末尾に、アプリケーションごとの設定ファイルをインクルードするように設定しておきます。# echo_supervisord_conf > /etc/supervisord.conf # echo "[include]" >> /etc/supervisord.conf # echo "files = supervisord/conf/*.conf" >> /etc/supervisord.conf
子設定ファイルの作成
svsqsという名前で最初に書いたスクリプトの起動設定をします。 自動起動や、自動復帰をONにします。# mkdir -p /etc/supervisord/conf/ # vim /etc/supervisord/conf/svtest.conf
[program:svsqs] command = /home/ec2-user/svsqs.rb process_name = svsqs autostart = true autorestart = true
supervisorのデーモン起動
ここまで設定できたらsupervisord自体を起動します。
# service supervisord start
supervisorのコンソールでstop/startテスト
supervisorctlというコマンドで管理対象プロセスの操作や状態確認が簡単にできます。
supervisorが起動すると、autostartがONになっているため対象のスクリプトも起動していることが分かります。
# supervisorctl svtest RUNNING pid 18770, uptime 15:44:07 supervisor> stop svtest svtest: stopped supervisor> status svtest STOPPED Jan 16 05:12 AM supervisor> start svtest svtest: started supervisor> supervisor> supervisor> status svtest RUNNING pid 10876, uptime 0:00:03 supervisor> supervisor> supervisor> exit
自動復帰の確認
プロセスを強制的に落としてみます。
するとsupervisorにより、新しいプロセスとして自動復帰します。
# ps -ax | grep svtest Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ 10876 ? S 0:00 /bin/sh /home/ec2-user/svsqs.rb 10892 pts/0 D+ 0:00 grep svtest # kill -9 10876 # ps -ax | grep svtest Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ 10898 ? S 0:00 /bin/sh /home/ec2-user/svsqs.rb 10901 pts/0 S+ 0:00 grep svtest
メッセージの確認
このプログラムで扱うSQSのキューに対し、いくつかメッセージを送ってみると、受信できているのがわかります。
# tail -1000f test.log D, [2014-01-16T07:02:28.085909 #13119] DEBUG -- : 10898 aaaaaa D, [2014-01-16T07:02:28.176748 #13119] DEBUG -- : 10898 ------- D, [2014-01-16T07:02:38.347694 #13119] DEBUG -- : 10898 bbbbbbb D, [2014-01-16T07:02:38.364416 #13119] DEBUG -- : 10898 cccccccc D, [2014-01-16T07:02:38.414742 #13119] DEBUG -- : 10898 ddddddd D, [2014-01-16T07:02:38.466001 #13119] DEBUG -- : 10898 ------- D, [2014-01-16T07:02:48.655003 #13119] DEBUG -- : 10898 eeeeeee D, [2014-01-16T07:02:48.666323 #13119] DEBUG -- : 10898 ffffffff D, [2014-01-16T07:02:48.718459 #13119] DEBUG -- : 10898 gggggggg D, [2014-01-16T07:02:48.771584 #13119] DEBUG -- : 10898 ------- D, [2014-01-16T07:02:58.947327 #13119] DEBUG -- : 10898 hhhhhhhh D, [2014-01-16T07:02:58.957724 #13119] DEBUG -- : 10898 iiiiiii D, [2014-01-16T07:02:59.023820 #13119] DEBUG -- : 10898 ------- D, [2014-01-16T07:03:09.171886 #13119] DEBUG -- : 10898 jjjjjjj
複数プロセス
次に、このプログラムを並列で複数のワーカーとして起動管理するようにしてみます。
# vim /etc/supervisord/conf/svsqs.conf
複数のプロセスとして管理するには、numprocsというパラメータを2以上に設定します。
また、このときprocess_nameにはワーカーの番号を含める必要があるため、
supervisorの特殊変数 %(program_name)と%(process_num)を利用します。
[program:svsqs] command = /home/ec2-user/svsqs.rb process_name = %(program_name)s_%(process_num)02d numprocs = 2 autostart = true autorestart = true
設定を変えたので再起動し、プロセスを見てみると、2つ起動しているのが分かります。
# /etc/init.d/supervisord restart
supervisorctlでは、先ほど設定した名前でワーカー名が動的に付与されているのが分かります。
[root@ip-10-160-79-47 ec2-user]# supervisorctl svsqs:svsqs_00 RUNNING pid 14286, uptime 0:36:24 svsqs:svsqs_01 RUNNING pid 14287, uptime 0:36:24
プロセスを落としてみると、自動で2プロセスにもどります。
# # ps -ax | grep rb Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ 14286 ? Sl 0:00 /usr/local/bin/ruby /home/ec2-user/svsqs.rb 14287 ? Sl 0:00 /usr/local/bin/ruby /home/ec2-user/svsqs.rb 14516 pts/0 S+ 0:00 grep rb # # kill -9 14286 # # ps -ax | grep rb Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ 14287 ? Sl 0:00 /usr/local/bin/ruby /home/ec2-user/svsqs.rb 14526 ? Rl 0:00 /usr/local/bin/ruby /home/ec2-user/svsqs.rb
また、ログをみてみると、2つのプロセスできちんと動作しているようです。
# tail -1000f test.log D, [2014-01-16T07:25:13.175073 #14287] DEBUG -- : 14287 ------- D, [2014-01-16T07:25:23.311352 #14286] DEBUG -- : 14286 aaaaaaaa D, [2014-01-16T07:25:23.326240 #14286] DEBUG -- : 14286 bbbbbbbb D, [2014-01-16T07:25:23.393122 #14286] DEBUG -- : 14286 ccccccc D, [2014-01-16T07:25:23.441076 #14286] DEBUG -- : 14286 ------- D, [2014-01-16T07:25:28.144026 #14287] DEBUG -- : 14287 ddddddd D, [2014-01-16T07:25:28.153058 #14287] DEBUG -- : 14287 ------- D, [2014-01-16T07:25:33.682118 #14286] DEBUG -- : 14286 eeeeeee D, [2014-01-16T07:25:33.735474 #14286] DEBUG -- : 14286 fffffff D, [2014-01-16T07:25:33.827446 #14286] DEBUG -- : 14286 ------- D, [2014-01-16T07:25:42.971976 #14287] DEBUG -- : 14287 ggggggg D, [2014-01-16T07:25:42.986925 #14287] DEBUG -- : 14287 ------- D, [2014-01-16T07:25:44.555526 #14286] DEBUG -- : 14286 hhhhhhh D, [2014-01-16T07:25:44.606725 #14286] DEBUG -- : 14286 ------- D, [2014-01-16T07:25:53.106090 #14287] DEBUG -- : 14287 jjjjjjjj D, [2014-01-16T07:25:53.118289 #14287] DEBUG -- : 14287 ------- D, [2014-01-16T07:26:01.609948 #14286] DEBUG -- : 14286 kkkkkkkk D, [2014-01-16T07:26:01.738742 #14286] DEBUG -- : 14286 ------- D, [2014-01-16T07:26:04.564231 #14287] DEBUG -- : 14287 llllllll D, [2014-01-16T07:26:28.385778 #14287] DEBUG -- : 14287 ------- D, [2014-01-16T07:26:34.210485 #14526] DEBUG -- : 14526 mmmmm D, [2014-01-16T07:26:34.301180 #14526] DEBUG -- : 14526 ------- D, [2014-01-16T07:26:39.204945 #14287] DEBUG -- : 14287 nnnnn D, [2014-01-16T07:26:39.224593 #14287] DEBUG -- : 14287 -------
こんな感じで、仮にプログラムがエラーでオチたりした場合でも、常に指定したプロセス数に起動しなおしてくれると助かります。
以上です。