バックエンド2025年12月 · 3分で読めます

通話中のセッションを切らずにリリースする ― バージョン保持型デプロイのパターン

COVID で需要が急増する中、リアルタイム動画接客プラットフォームの WebRTC セッションをデプロイ越しに維持し続けた仕組み。

2年間、リアルタイム動画接客プラットフォームの開発に関わった ― 銀行アドバイザリー、オンライン診療、アパレル小売の商品デモを、すべて WebRTC で配信。MVP は小規模では動作していたが、COVID で需要が急増し、デプロイのたびに同じ壁にぶつかっていた。

壁は見かけは単純だった:リアルタイム通話中にリクエスト断が起きる場所として、これ以上に最悪な場所はない。標準的なゼロダウンタイムデプロイ(ローリング再起動、ロードバランサのドレインなど)はどれも、進行中セッションが宙吊りになる、リトライする、あるいは切断される時間帯を持つ。2分のサポート通話なら不便で済むが、30分の銀行コンサルティングなら、それは失った顧客だ。

効かなかったもの

最初の本能はデプロイを瞬間化する ― ロールアウト時間を短くすることだった。試した。時間は短くなり、切断は減ったが、故障モードは変わらなかった。誰かが、どこかで、悪い時間帯にあたる。

次の本能はスティッキーセッション:接続したバージョンにユーザーをルーティングし続ける。理論上は動くが、アプリケーションのシグナリング状態(DB の行、キャッシュエントリ、ロック)を別バージョンが触った瞬間に破綻する。スティッキールーティングは状態の整合性を保証しない。

効いたパターン

『前のバージョン』を引退させるものと考えるのをやめた。代わりに、すべてのリリースは前のビルドを保持ウィンドウの間、稼働させ続ける。古いセッションは開始時のバージョンで完結する。新しいセッションは新バージョンで処理される。どの通話もミッドフライトでバージョンが入れ替わることはない。

実装としては:

  • 保持ウィンドウ中は、新旧2つのビルドが並行稼働
  • 上流の小さなルーターが既存セッションを元のバージョンへマッピング
  • アクティブセッションが自然終了するのを待つコネクションドレイン、最大保持時間で上限を設定

文字通りのゼロダウンタイムではない ― 2バージョンが同時稼働している。それより良いもの ― ゼロ・ディスラプション。ユーザーから見えるシステムには、そもそもバージョンの概念がない。

違う形でやるとしたら

保持ウィンドウの値は、慎重に選ばなければならないパラメータだ。短すぎれば切断に戻る。長すぎれば古いバージョンが滞留する。

当時のセッション長分布に合う値を見つけたが、次にやるなら、デプロイツール側に組み込みたい ― 直近のセッション長 P95 に応じて、ウィンドウを動的に調整する設計にしたい。正解の値は定数ではない;ユーザーの実利用パターンの関数であり、それは変動する。