【ITニュース解説】Unicast vs. Anycast for Webhook Ingress: Cutting Handshake Latency for Global Senders
2026年10月24日に「Dev.to」が公開したITニュース「Unicast vs. Anycast for Webhook Ingress: Cutting Handshake Latency for Global Senders」について初心者にもわかりやすく解説しています。
ITニュース概要
Webhook通信は、遠い相手だと接続確立(ハンドシェイク)に時間がかかり、応答遅延の元になる。Anycastは最短経路を選び、TCP Fast OpenやTLS 1.3 0-RTTは接続回数を減らして遅延を改善する。ただし、リプレイ攻撃対策やデータ重複排除、サーバー側の迅速な処理も不可欠だ。
ITニュース解説
システムエンジニアを目指す初心者の皆さん、今回はWebhook(ウェブフック)の通信で発生する遅延を減らし、安定したシステムを構築するための重要な技術について解説する。Webhookとは、Stripe、GitHub、Shopifyといった世界中のサービスが、皆さんのサーバーにイベント通知をリアルタイムで送る仕組みだ。例えば、商品が購入されたり、コードが更新されたりといったイベントが発生した際に、その情報を皆さんのアプリケーションが自動的に受け取って処理できるようになる。
しかし、このWebhook通知が皆さんのサーバーに届くまでに、いくつかの通信上の準備が必要で、これに時間がかかると通知が遅れたり、最悪の場合はタイムアウトして通知が失敗したりする。特に、多くのサービスはWebhookの通知に対して非常に短い時間での応答を求めている。例えば、GitHubは10秒以内、Shopifyは接続タイムアウトが1秒、全体で5秒以内、Slackは3秒以内といった具体的な制約がある。この時間内に応答がないと、送信側は失敗と判断し、何度も再試行を行うことになり、システムに負荷がかかる原因にもなる。
Webhookの通知が送信されてから皆さんのサーバーがデータを受け取るまでには、主に次のステップとそれにかかる往復時間(RTT:Round Trip Time)がある。 まず、皆さんのサーバーのIPアドレスを調べるための「DNSルックアップ」。これは送信側のDNSサーバーの状況による。 次に、通信経路を確立する「TCPハンドシェイク」。これは通常1回のRTTを要する。 続いて、通信を暗号化する「TLSハンドシェイク」。TLS 1.2では2回のRTT、最新のTLS 1.3では1回のRTTが必要となる。 最後に、実際のイベントデータを送信する「HTTP POSTリクエスト」と、それに対する皆さんのサーバーからの「応答」だ。これには1回のRTTと、皆さんのサーバーでの処理時間が加わる。
例えば、アイルランドのダブリンにあるサービスから、アメリカのバージニア州にある皆さんのサーバーへWebhookを送信する場合、1回のRTTが約75ミリ秒かかると仮定しよう。TLS 1.3を利用すると、TCPハンドシェイクに75ミリ秒、TLSハンドシェイクに75ミリ秒、HTTPリクエストと応答に75ミリ秒で、合計約225ミリ秒がデータ送信から最初の応答までの時間となる。TLS 1.2ではさらに時間がかかり、約300ミリ秒にもなる。これらの時間には、DNS解決やサーバーでのアプリケーション処理時間は含まれていない。
このような「ハンドシェイク」にかかる数百ミリ秒の時間は、短いように思えるが、Shopifyの1秒といった厳しい接続タイムアウトがある場合には、ボトルネックになり得る。ただし、Webhookがタイムアウトする主な原因は、ハンドシェイクの遅延よりも、皆さんのアプリケーションでの処理が遅いことによる場合が多いことも理解しておくべきだ。また、HTTP Keep-Aliveなどの機能で接続が再利用される場合、ハンドシェイクのコストは最初の接続時のみ発生し、同じサーバーへの後続のイベント通知では省略される。
では、このハンドシェイクにかかる往復時間を短縮するにはどうすればよいか。ここで「Unicast(ユニキャスト)」と「Anycast(エニーキャスト)」というネットワークのルーティング方式が重要になる。
Unicastは、皆さんのサーバーのIPアドレスがインターネット上の特定の物理的な場所(例えば、一つのデータセンター)に対応付けられている状態を指す。世界中のどこからWebhookが送られてきても、すべての通信はその一点を目指してインターネットを横断する。そのため、送信元と皆さんのサーバーの距離が離れていると、それだけ通信に多くの往復時間が必要になる。
一方、Anycastでは、同じIPアドレスを、地理的に離れた複数の場所に配置されたサーバー群(Points of Presence、略してPoPと呼ぶ)が同時に「自分はこのIPアドレスに対応している」とインターネットに宣言する。すると、送信元からの通信は、インターネットのルーティングポリシー(経路選択のルール)に従って、その送信元から見て「ネットワーク経路が最短である」、つまり「論理的に最も近い」PoPに届けられる。これにより、送信元とPoP間の通信距離が短縮され、結果としてRTTが大幅に短縮される。例えば、先ほどの75ミリ秒かかっていた往復時間が、Anycastを使うことで15ミリ秒程度にまで短縮される可能性もある。
Anycastは非常に効果的だが、運用にはいくつかの側面を考慮する必要がある。Anycastを実装するには、皆さんのネットワークがBGP(Border Gateway Protocol)という、インターネットの経路情報を交換するためのプロトコルを利用し、特定のIPアドレス範囲を複数のPoPから同時にアナウンスする必要がある。これには、独自のIPアドレス空間とAS番号(自律システム番号)が必要となるか、Anycastネットワークを運用しているクラウドプロバイダーやCDNサービスを利用することになる。 また、Anycastにおける「最も近い」とは、物理的な距離ではなくネットワーク的な経路の近さを意味することに注意が必要だ。まれに、通信中にPoPが切り替わることがあり、その場合TCP接続が切断される可能性がある。しかし、Webhookの通信は短命なHTTPリクエストなので、影響は比較的少ない。送信側は通常、失敗した通知を再試行する仕組みを持っているため、問題は緩和される。
Anycast運用の重要な側面として、もしPoPのサーバーが故障したにもかかわらず、そのPoPがIPアドレスをアナウンスし続けていると、そのPoPにルーティングされた通信が「ブラックホール化」(データがどこにも届かず消滅すること)してしまう。これを防ぐため、各PoPは自身のヘルスチェックを行い、異常を検知した際には自動的にIPアドレスの経路情報をインターネットから「引き抜く」仕組みが必要だ。これにより、正常に動作している別のPoPへ通信が誘導されるようになる。
次に、個々の往復回数を減らすための技術を見てみよう。一つは「TCP Fast Open (TFO)」だ。これは、一度接続したことのあるサーバーに対して、再接続する際に、最初のSYNパケットにデータを少し含めて送信できるようにする技術だ。これにより、TCPハンドシェイクにかかる1往復を省略できる可能性がある。しかし、TFOは送信側のクライアントが対応している必要があり、一部のネットワーク機器がTFOを含むパケットを正しく処理できない場合がある。また、TFOで送られたデータが重複して届く可能性があるため、アプリケーション側で同じ操作を何度行っても同じ結果になる「べき等性」が求められる。
もう一つは、TLS 1.3の「0-RTT (Zero Round Trip Time) リジュンプション」だ。これは、以前に接続したセッション情報(セッションチケット)を再利用することで、クライアントがTLSハンドシェイク完了前に、最初のパケットにアプリケーションデータを含めて送信できるようにする技術だ。これにより、TLSハンドシェイクにかかる1往復を省略できる可能性がある。しかし、TFOと同様に送信側のクライアントがTLS 1.3と0-RTTに対応している必要があり、さらにセキュリティ上の重大な問題がある。0-RTTで送られたデータは「リプレイ攻撃」の危険性があり、攻撃者によって同じデータが複数回送信されてしまう可能性がある。Webhookの通知は通常、データをサーバーに送信するPOSTリクエストであるため、もし0-RTTで送られたPOSTリクエストがリプレイされると、同じイベントが何度も処理されてしまう恐れがある。そのため、厳密にべき等性が保証されたWebhookハンドラーでのみ利用すべきであり、POSTリクエストでは推奨されないことが多い。
これらの技術を組み合わせると、ハンドシェイクにかかる時間を大幅に短縮できることがわかる。例えば、Anycastを使ってRTTを15ミリ秒に短縮し、TLS 1.3を利用すれば、最初の応答が返ってくるまで約45ミリ秒となる。さらに、もしTFOが利用できれば約30ミリ秒、0-RTTまで利用できれば理論上は約15ミリ秒にまで短縮可能だ。しかし、TFOや0-RTTは送信側の協力が不可欠であり、リプレイ攻撃などのリスクも伴うため、最も確実で効果的な改善策は、送信側の変更を必要としないAnycastであると言える。
これらの高速化技術を導入しても、皆さんのアプリケーションでの処理が遅ければ、結局はタイムアウトの原因となる。Webhook通知を素早く処理し、送信側に応答を返すためのベストプラクティスは、「エッジでの迅速な応答と、非同期での処理」だ。つまり、Webhookを受け取ったPoP(またはサーバー)は、できるだけ早く通知の署名を検証し、イベントデータを永続的なキュー(例えばApache KafkaやAmazon Kinesisなど)に格納したら、すぐに2xx系のHTTPステータスコード(例: 200 OK)を送信元に返す。そして、実際のイベント処理は、キューからイベントを読み出して非同期に行うべきだ。これにより、送信元の厳しいタイムアウト要件を満たしつつ、アプリケーションの処理負荷を分散できる。この際、複数のPoPがあるAnycast環境では、セッション情報や重複排除の情報をPoP間で共有する必要がある。Webhookの送信元は、ネットワークの問題などで同じイベントを複数回送信することがあるため、皆さんのアプリケーションは、イベントIDなどを使って重複したイベントを適切に処理する「べき等な」設計にしておくことが非常に重要だ。
最後に、これらの改善策を導入する際には、必ず導入前と導入後で性能を測定することが大切だ。curlコマンドのようなツールを使って、DNS解決時間、TCP接続時間、TLSハンドシェイク時間、そして最初の応答が返ってくるまでの時間を測定できる。これらの測定結果と、サーバーのログやカーネルカウンターを照らし合わせることで、どの技術がどれだけ効果があったのか、どの送信元が恩恵を受けているのかを具体的に把握することができる。
結論として、世界中に分散したWebhookの送信元からの通知に対して、最も効果的で信頼性の高いレイテンシ改善策は「Anycast」だ。Anycastは、送信元が変更することなく、すべての通信の往復時間を短縮してくれる。これに加えて、PoPの健全性チェックと経路の自動引き抜き、TLS 1.2との互換性を保ちながらのTLS 1.3の導入、そして迅速に応答し、後で処理するためのエッジでのキューイング戦略を組み合わせることが理想的だ。TCP Fast Openは送信元が対応していれば有効だが、TLS 1.3の0-RTTはリプレイ攻撃のリスクが高いため、厳密にべき等性が保証された特殊なエンドポイントでのみ、慎重に利用すべきであると理解しておくべきだ。