SQS: ワーカープロセスの稼働管理にSupervisordが便利
SQS等のキューを介して非同期に処理を行う Queue Chain パターンを実装する場合、SQSに突っ込む処理はWebアプリ等の処理中に書けばよいので特に考えることはないが、SQSからメッセージを抜いて後続の非同期処理を実行するワーカープロセスをどのように起動管理するか?が肝になる。非同期処理を出来るだけ早く処理したい場合は特に。
JavaならMDB(Message Driven Bean)のような仕組みがすでにあるが、軽量言語(PHP,Pearl, Ruby, Python,etc)向けに何かうまい方法を用意したい。Cronで1分間隔起動だと、処理時間によっては重複起動になるし、そもそも分単位での制御しかできないので出来れば常駐化させたい。言語ごとには解決策があるのかもしれないが、もう少し汎用的な仕組みが欲しい。
で、辿り着いたのが Supervisord というプロセスをデーモン化(daemonize)するデーモン。昔で言うところの daemontools のイメージ。
daemontoolsから改善されている点としては
- 複数の種類のプログラムを一つのSupervisord配下で管理できる
- あるプログラムを任意の数のプロセスだけ起動できる
- 管理ツール( supervisorclt )で各種の情報取得や制御が可能
- Web UIが付いている
- 動的に設定変更が可能
あたりか。
んで、結局どうなるのか?というと
という感じ。上図は、SQSを定期的に監視・取得するプロセス群、CloudWatchを定期的に監視・取得するプロセス群、クローラがいる例。
- 「一定回数だけキューを監視・取得して処理をするスクリプト」を書く
- スクリプトをSupervisordに登録する
- スクリプトを実行するプロセスがSupervisordによって複数起動する。
- 各プロセスはスクリプトを実行する(キュー監視・実行を行為、一定回数ループすると終了)。
- 終了したプロセスのスロットは、Supervisordによって、新しくプロセスが生成される。
あとは、ループごとに行うsleepの間隔と、同時実行プロセス数の調整をすることで、キューの捌きの処理能力をある程度制御出来るようになる。
具体的な例は後ほど。