はじめに
こんにちは、バックエンド/インフラ担当の森井です。 最近Server-Sent Eventsを触っていたのですが、負荷分散はNLBを使わないといけない気がするな〜面倒くさいな〜と思いながらALBを通してみたら、普通に動いたので驚きました。
Server-Sent Eventsとは
Server-Sent Eventsは、HTTP接続によりサーバーからクライアントへとデータを継続的に送信できる技術です。 詳しくはMDNの説明をご覧ください。
継続的に更新されるデータをクライアントに配信したい場合、最も原式的な方法はポーリングです。 ポーリング方式とServer-Sent Events方式の比較を図示してみました。 データ更新するたびに接続しなおす必要がないので、更新頻度が高い場合はリソース効率がよい方式だと言えます。
よく比較される技術としてWebSocketがありますが、WebSocketが双方向でデータ送信できるのに比べ、Server-Sent Eventsは双方向ではなくサーバーからクライアントへの単方向のデータ送信となる点が最も大きな違いです。
ALBにServer-Sent Eventsのサーバーを登録してみた
ALBでServer-Sent Eventsが動くのか、実際に試してみました。 普通にEC2にホストしただけなので具体的な内容は割愛しますが、一応構成を示しておこうと思います。 バックエンド側のプログラムはGoで作成し、クライアントからはcURLでアクセスしました。 多数同時接続も試してみましたが、かなりサクサク動いてくれて満足です。
ちなみに、GoでServer-Sent Eventsを実装するのはかなり簡単でした。 実装方法が知りたい方は下記のブログが参考になると思います。
Go言語でServerSentEvents(SSE) #Web - Qiita
Server-Sent Eventsが動かなさそうだと思っていた理由
ネットワーク詳しい方からしたらL7ロードバランサーなんだから動いて当たり前じゃんと思われるかもしれませんが、私が動かなさそうだなと思ってしまったのには理由があります。
Server-Sent Eventsとよく比較されるWebSocketについては、ALBが対応していることがドキュメントに明記されていたのです。
Application Load Balancer は、 のネイティブサポートを提供します WebSockets。HTTP 接続アップグレードを使用して、既存の HTTP/1.1 接続を WebSocket (ws または wss) 接続にアップグレードできます。アップグレードすると、リクエストに使用される TCP 接続 (ロードバランサーとターゲット) が、ロードバランサーを介したクライアントとターゲット間の永続的な WebSocket 接続になります。HTTP WebSockets リスナーと HTTPS リスナーの両方で を使用できます。リスナーに選択したオプションは、 WebSocket 接続と HTTP トラフィックに適用されます。詳細については、「Amazon CloudFront デベロッパーガイド」の WebSocket 「プロトコルの仕組み」を参照してください。
Application Load Balancer のリスナー - Elastic Load Balancing
似た用途で使われるWebSocketが明記されているのに、Server-Sent Eventsについては何も書いていないということは、動かないのでは?と思ってしまったのでした…. WebSocketもServer-Sent EventsもHTML Living Standardに記載されているのに、この扱いの違いは何なのか気になります。やはり利用者数でしょうか。
(9/13追記)
このブログを読んだエンジニアの先輩から、社内チャットで以下のコメントをいただきました。
WebSocket は最初に HTTP が仲介するけど最終的には Upgrade で別プロトコルになる一方、Server-Sent Events は HTTP プロトコルで実現されるからでは。「HTTP に対応してる」という言及に Server-Sent Events は含まれる(HTTP に対応してるならその中で実現できる)けど、WebSocket は含まれないから、という気がする。
Upgradeヘッダーを挟むかどうか盲点でした。Upgradeは通信プロトコルをアップグレードする仕組みなので、アップグレード後は別プロトコル扱いというのは納得です。
おわりに
何事も検証することが大事ですね。
余談ですが、最初は「ALBは使えないから、NLBだとTLS終端がターゲット側になって面倒くさそうだなー」と思っていましたが、NLBでもTLSの終端をしてくれるみたいですね。AWSさん流石です。
新機能 – Network Load Balancer の TLS 終端 | Amazon Web Services ブログ