2018年にHerokuでResqueをGraceful Shutdownする
Graceful Shutdownについては下記記事で丁寧に説明されているので割愛します。
しかし、下記の記事ではheroku上でGraceful Shutdownを行うことができません。
https://blog.yuyat.jp/post/graceful-shutdown-resque-in-heroku/
(ResqueのREADMEにも書いていることなのですが)
なぜなら、herokuのdynoはSIGTERMをすべてのプロセスに送信するので、 RESQUE_PRE_SHUTDOWN_TIMEOUT
の秒数だけ待ってくれないのです。
解決方法は、下記gemをインストールするだけでOKです。
https://github.com/iloveitaly/resque-heroku-signals
また、heroku環境ではSIGTERMを受けてから30秒以内にプロセスを停止しないと強制終了されてしまうので、実行中のタスクを正常に停止する要件は必須になります。
処理中のタスクが最初から30秒以内で終了することが見込まれているのであれば、対策は不要ですが、30秒以上かかるタスクの場合はSIGTERMを受けたことを想定して実装しなければなりません。
具体的な例をあげると、外部サーバからの問い合わせ結果をDBに保存する場合はSIGTERMの割り込みによって結果を保存できないことがありえます。他には、大量メール送信中にSIGTERMの割り込みが入って再度送信してしまい2重送信もあるでしょう。
どう実装するかというと、 SIGTERMを受けるとResque.heroku_will_terminate?
が true
を返すので、割り込まれたくない処理の前にResque.heroku_will_terminate?
でチェックしてリトライ処理にするのです。
以上。
-
category:
- ruby tags: