メインコンテンツへ移動
JA
ホーム / 技術ブログ / 無停止でスケール・デプロイするための設計
2026年6月11日 · Z-SOFT Admin · 読了目安 5 分

無停止でスケール・デプロイするための設計

Readiness、オートスケール、Graceful Shutdownを連携し、利用者を切断せずにデプロイします。

記事一覧へ戻る

要点: 停止時間の多くは、能力不足だけでなく、システムが切り替わる瞬間に発生します。

この記事の用語: Readiness:トラフィックを受けられる状態。Drain:新規受付を止め、処理中リクエストを完了させること。

現場の課題

新しいプロセスが準備前に通信を受けたり、古いプロセスが処理中のまま停止されたりすると障害になります。CPU平均だけでは、この二つの問題を検知できません。

単純な対策だけでは不十分な理由

オーケストレーター、ロードバランサー、アプリケーションが、いつトラフィックを受け、いつ処理完了とみなすかで一致する必要があります。Readinessが早すぎても、外部依存を見すぎても停止を招きます。

処理フロー

メトリクス
p99と飽和度
Autoscaler
早めに台数追加
Readiness
依存先を確認
ロードバランサー
安全な通信だけ転送
新規InstanceはReadiness通過後に初めて参加し、旧InstanceはDrainしてから終了します。

アーキテクチャ上の判断

飽和の前にスケールする

p95/p99 遅延、Active 同時実行数、最古ジョブの待ち時間、依存先の飽和度を指標にします。Image Pull、プロセス起動、Readiness Delay、キャッシュ Warm-upにかかる時間を見込み、その分だけ早めに処理能力を追加します。

Readinessは有意味かつ局所的にする

通信の処理に必要な設定と、重要なLocal依存だけを確認します。すべてのDownstreamに依存させると、一つのRemote障害だけで、本来使えるレプリカまで全て外れてしまいます。

終了の前にDrainする

SIGTERMを受け取ったら、まずUnreadyにしてロードバランサーへの反映を待ちます。新規のBackground ジョブ取得を止め、実行中のリクエストを完了し、その後で有限のGrace Period内にDBとブローカーの接続を閉じます。

さらに深く考える

Probeは一般的なHealthではなくライフサイクルを表す

Startup Probeは、遅い初期化をLivenessによる再起動から守ります。Livenessはプロセスが前進できるかを答えるもので、通常は局所的にします。DB障害で全アプリケーションのレプリカを同時に再起動させてはいけません。ReadinessはDrain中や、本当に必須な依存を失ったときに変化してよい指標です。可能であれば、Probe Handlerを過負荷のリクエスト プールから切り離し、その遅延も計測します。常にSuccessを返すProbeは無意味ですが、依存サービス Graph全体を再帰的に確認するProbeも、提供可能な処理能力を全て外して障害を増幅する危険があります。

処理能力 Planningには変更中の余力も含める

通常のトラフィックに加えてRolling Updateを行うには、Surge 予備能力が必要です。ピーク 同時実行数、Instance当たりのSafe 同時実行数、そして1つの障害領域喪失から、Minimum Healthy レプリカを計算します。次に、StartingとDrainingのInstanceがReady 処理能力を最小値より下げないよう、maxUnavailableとmaxSurgeを選びます。オートスケールにはStabilization Windowが必要で、Rollout自体が生む一時的なメトリクスに反応しないようにします。キュー コンシューマーでは、終了をLeaseや処理権限の有効時間と調整します。WebSocketやStreamingの通信では、通常のHTTP Drainの前提が当てはまらないため、Reconnectの動作を定義します。

実装手順

  1. 平均値だけでなく、P99遅延、資源飽和度、キュー待ち時間でスケールします。
  2. Livenessは単純に保ち、Readinessでトラフィックを受けられるかを判断します。
  3. 終了時は新規トラフィックを止め、処理中リクエストを完了してから依存接続を閉じます。

コード例: アプリケーション終了の状態機械

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

Shutdownの期限は、通常の最大リクエスト時間より長く、それでいて有限にします。長時間のデータ出力はHTTPを開いたままにせず、Lease 復旧付きの非同期ジョブにします。

想定しておく障害

  • マイグレーション、プール、必須設定の準備が整う前に、ReadinessがHealthyになってしまいます。Startup Probeと、順序を明確にしたInitialization Barrierを使います。
  • Readinessの変更後も、ロードバランサーが通信を送り続けます。実際のPropagation Timeを測り、Pre-stop DelayとTermination Graceに含めます。
  • Auto ScalingとRolling Updateが、同時に処理能力を減らします。maxUnavailable、Surge 処理能力、Disruption Budgetを、同じ最小健全容量モデルから決めます。

監視すべきこと

指標何が分かるか
利用者視点のSuccess Rateとp99実際のリクエストが成功し続け、遅延目標の範囲内にあるときだけ、リリースをHealthyと判断できます。
Ready・Starting・Drainingのレプリカ数実行中のプロセスをすべて処理能力とみなすのではなく、ライフサイクルの遷移を可視化します。
終了時のIn-flight リクエスト数0を超える強制終了は、Drain時間の不足かStuck リクエストの存在を示します。
デプロイ中のエラー-budget Burn小さな失敗が全Rolloutへ広がる前に、自動的に一時停止またはロールバックできます。

設計の検証方法

  • Rolling Update中に実リクエストを連続で送信し、Success率、p99、接続 Resetがいずれも目標内に収まるか確認します。
  • Startup依存を通常のWarm-up以上に遅延させ、早期に通信を受けずに再起動 Loopを防げるか検証します。
  • 短時間・長時間のリクエストを実行中にInstanceを終了し、期限の前に新規割り当てが止まるか確認します。
  • デプロイ中に1つのAvailability Zoneを外し、Disruption BudgetがMinimum Healthy 処理能力を守るか試験します。
  • 不良なリリース Signalを発生させ、自動一時停止またはロールバックがエラーバジェット内で完了するか測ります。

本番導入の進め方

起動時間、ロードバランサーの反映時間、最長リクエスト時間を測ります。小さなグループでDrainを有効化し、強制終了を確認した後、SLOに基づく一時停止とロールバックを導入します。

本番前チェックリスト

  • Readinessの確認項目が多すぎると、値が揺れて正常な台数まで外れてしまいます。
  • スケール条件には、Warm-up時間も含めます。
  • 本番前に、実運用相当の同時実行数でRolling Updateを検証します。

まとめ

無停止デプロイは、準備、受付、Drain、終了までのトラフィックのライフサイクルを管理することです。

Z-SOFTとの協業

今日のテクノロジーに関する一つひとつの判断が、その後の何年にも影響を与えます。

現状を評価し、目標を明確にし、企業の成長方針に合ったアーキテクチャを選定するために、Z-SOFTのチームにご相談ください。

相談を予約する