こんにちは!インフラ・ネットワークの世界へようこそ。世界中のウェブサイトやアプリが日々やり取りしているデータ通信の裏側を覗いてみると、そこにはまるで人間の社会のような、実によくできた「お辞儀と終わりの作法」が存在しています。
今日は、次世代のウェブ通信規格である「HTTP/2」の裏側で、いぶし銀の活躍をしている「GOAWAY(ゴーアウェイ)フレーム」についてお話しします。
「接続をきれいに終わらせる」なんて、一見地味なテーマに思えるかもしれませんが、ここにはネットワークエンジニアのロマンと、システムを優しく安全にシャットダウンするための知恵が詰まっています。一歩ずつ、身近な例えから紐解いていき手にとるように理解していきましょう!
—
1. HTTP/2の「マルチプレクシング」という名の超特急列車
まず、今日の主役であるGOAWAYを理解するために、HTTP/2の基本である「マルチプレクシング(多重化)」のお話を少しだけさせてください。
昔のHTTP/1.1という時代は、一本の道路(TCPコネクション)につき、一台の車(リクエストとレスポンス)しか走らせることができませんでした。そのため、画像やテキストをたくさん読み込もうとすると、道路の入口で大渋滞が起きていたんです。
これがHTTP/2になるとどうでしょう?
一本の太い道路(TCPコネクション)の中に、何本もの「専用レール(ストリーム)」を敷き、その上をたくさんの荷物(データ)を乗せたトロッコが、同時にビュンビュン往来できるようになりました。この仕組みをマルチプレクシングと呼びます。
郵便配達の例えで考えてみましょう
あなたの家(ブラウザ)と、大きな倉庫(Webサーバー)の間を結ぶ「一本の大きな専用道路」があると想像してください。HTTP/2はこの道路の上に、番号の振られた無数のレーン(ストリーム)を作ります。
- 1番のレーン:トップページのHTMLを送るトロッコ
- 3番のレーン:お洒落なロゴの画像を送るトロッコ
- 5番のレーン:お買い物のデータを送るトロッコ
このトロッコたちは、バラバラに出発したとしても、途中で追い抜いたりしながら効率よくあなたの手元に届きます。とても便利ですよね!
—
2. でも、お片付け(接続の終了)のとき、どう困る?
さて、この「一本の道路にたくさんのトロッコが走っている」という状態のとき、サーバー側のメンテナンスや、一定時間が経過したことで「そろそろこの道路を閉じたいな」と思ったとします。
ここで、昔の雑なやり方をしてしまうと、大惨事になります。
もしサーバーがいきなり「はい、おしまい!道路のゲートを閉めます!」とパチンと電源を切ってしまったらどうなるでしょう?
今まさに5番のレーンを走っていた「お買い物データ」のトロッコは、途中で壁に激突して中身がパーになってしまいます。「えっ、今お金を払うボタンを押したのに!注文は完了したの?」と、ユーザーは大パニックですよね。
かといって、サーバーが「新しいトロッコはもう入れないでおこう。今走っているトロッコが全部ゴールするまで、何時間でも待ち続けよう」とすると、意地悪なユーザーがいつまでもトロッコをゴールさせないことで、サーバーがずっと道路を閉じられなくなってしまいます(リソースの枯渇)。
ここで登場するのが、今回の主役である「GOAWAYフレーム」なんです!
—
3. GOAWAYフレームの正体と、その優しい役割
GOAWAYフレームとは、一言で言うと「サーバーからクライアントへ送る『そろそろこの道路を閉鎖するので、新しいトロッコを出すのはストップしてね。あ、ちなみに〇番までのトロッコは責任を持って最後まで面倒を見るよ』という丁寧なお手紙」です。
このGOAWAYの中には、主に次のような重要なメッセージが書かれています。
1. 「もう新しいストリーム(トロッコ)を作らないでね」という宣言
2. 「最後にちゃんと処理できた(あるいは処理中の)ストリームIDの番号」
この「最後に処理できたストリームID」というのが、めちゃくちゃ重要なポイントです。
レストランのラストオーダーに似ています
居酒屋で「そろそろお時間ですので、ラストオーダーの注文をどうぞ。これ以降の追加注文は受け付けられません」と店員さんが教えてくれるシーンを想像してください。
GOAWAYはまさにネットの世界の「デジタル・ラストオーダー」です。
サーバーは、「私はこれまで番号 `5` までの注文票を受け取りました。だから、君(クライアント)が `1` から `5` 番のレーンで送ってきたリクエストまでは最後まで責任を持って料理(レスポンス)を作ります。でも、もし `7` 番とか `9` 番といった、まだ出発させていない新しいトロッコがあったら、それはもう諦めて別の道路(新しい接続)から送ってくださいね」と伝えるのです。
これにより、サーバーとクライアントの間で「どこまで話が進んでいたか」の認識が完全に一致し、データが途中で消えてしまう事故を防ぐことができます。これが正常な切断ハンドリングです。
—
4. 実際の通信の裏側を覗いてみよう
ネットワークの裏側(パケットキャプチャやログ)を覗くと、このGOAWAYのやり取りは以下のような流れで行われています。
[クライアント (ブラウザ)] [サーバー]
| |
|—- (ストリーム #1: ページ要求) —->|
|—- (ストリーム #3: 画像要求) —–>|
| |
| (あ、メンテナンス時間だ!接続を閉じよう)
| |
|<--- (GOAWAY: 最後のID = #3) -------| <-- サーバーからの通告
| |
|---- (ストリーム #5 を作ろうとする) ->| <- X サーバーに拒否される
| |
|<--- (ストリーム #3 のお返事) ------| <-- 最後までしっかり処理
| |
|======== (お互いに安全に切断) ========|
クライアントは、サーバーからGOAWAYフレームを受け取ると、「そっか、最後のIDは #3 なんだな。じゃあ #3 までの返事を待って、この道路はおしまいにしよう」と理解し、必要であれば別の新しいTCP接続(道路)を新しく張り直して、残りの通信をそちらに引き継ぎます。
—
5. 現場のエンジニアが知っておくべきポイントとまとめ
私たちが普段何気なく使っているWebブラウザやスマートフォンアプリは、このGOAWAYフレームの受信を裏側で非常にうまくハンドリングしています。
もしあなたがアプリケーションやプロキシサーバー(NginxやEnvoyなど)のチューニング、あるいは独自のHTTP/2クライアントを実装する立場になったときは、この「GOAWAYを受け取ったあとに、新しいストリームを作らないこと」、そして「未処理のストリームが正しく救済されているかログで追うこと」が、安定したインフラを作るための大きな鍵になります。
「道路をただ乱暴に塞ぐのではなく、走っている車を確認してから、お互いに納得の上でゲートを閉じる」
HTTP/2のGOAWAYフレームは、そんなデジタル世界の上品で確実なマナーそのものなんです。
難しいプロトコルの仕様書も、こうして身近な例えと結びつけていくと、パケットたちが生き生きと働いている様子がイメージできて楽しくなってきますよね。
それでは、また次回のマニアックなネットワーク解説でお会いしましょう!
コメント