TL;DR
- Go では
signal.NotifyContextとcontext.WithTimeoutを組み合わせて graceful shutdown を実現する。 - HTTP サーバは
net/httpのShutdownメソッドで安全に止められる。
内容
Graceful shutdown とは
Graceful shutdown は、処理中のタスクのリソースを解放してから、アプリケーション自身を終了することである。SIGTERM を受け取ってから SIGKILL で強制終了されるまでの間に、リソースを解放する。
Go での実現
Go では、signal.NotifyContext と context.WithTimeout を組み合わせる。signal.NotifyContext を使うと、OS からの SIGTERM を ctx.Done() で受け取れる。context.WithTimeout でタイムアウトを設定したコンテキストを Shutdown メソッドに渡し、決めた時間内にシャットダウン処理を終えるようにする。
HTTP サーバは、net/http の Shutdown メソッドで安全に止められる。Shutdown はすべてのリスナーを閉じてからアイドル状態のコネクションを閉じる。アイドル状態のコネクションを閉じ終えるか、タイムアウトした時点で終了する。
実運用
発表者の会社では、メールの一括送信を非同期で始めた後、デプロイによる終了で送信処理が途中で止まった。そこで、非同期タスクマネージャで graceful shutdown を実装し、運用している。登録した非同期タスクが完了するまで、シャットダウンを待つ。
キーワード
- Go
- Graceful shutdown