要点: 停止時間の多くは、能力不足だけでなく、システムが切り替わる瞬間に発生します。
この記事の用語: Readiness:トラフィックを受けられる状態。Drain:新規受付を止め、処理中リクエストを完了させること。
現場の課題
新しいプロセスが準備前に通信を受けたり、古いプロセスが処理中のまま停止されたりすると障害になります。CPU平均だけでは、この二つの問題を検知できません。
オーケストレーター、ロードバランサー、アプリケーションが、いつトラフィックを受け、いつ処理完了とみなすかで一致する必要があります。Readinessが早すぎても、外部依存を見すぎても停止を招きます。
設計と実装
- 平均値だけでなく、P99遅延、資源飽和度、キュー待ち時間でスケールします。
- Livenessは単純に保ち、Readinessでトラフィックを受けられるかを判断します。
- 終了時は新規トラフィックを止め、処理中リクエストを完了してから依存接続を閉じます。
実装例
RUNNING --SIGTERM--> DRAINING
DRAINING: readiness = false
DRAINING: Queue Jobの新規取得停止
DRAINING: Load Balancer反映待ち
DRAINING: await inFlightRequests == 0
DRAINING: DB・Broker PoolをClose
DRAINING --deadline--> TERMINATED
terminationGrace >= propagation + maxRequest + cleanup本番導入の進め方
起動時間、ロードバランサーの反映時間、最長リクエスト時間を測ります。小さなグループでDrainを有効化し、強制終了を確認した後、SLOに基づく一時停止とロールバックを導入します。
まとめ
無停止デプロイは、準備、受付、Drain、終了までのトラフィックのライフサイクルを管理することです。
