WebSocket対応した噂のALB (Application Load Balancer) を試してみた
TL;DR
- 2016年8月にAWSのLoad Balancerが WebSocketに対応した
- スムーズすぎて心配になるくらい簡単に導入できる
- 「うまい、はやい、やすい」ので、導入しない理由はないと思う
ALB Release!
巷では長らく噂になっていた、新しいAWSのLoad Balancer。 先月2016年8月11日についにリリースされた。待望のL7対応だ。
個人的に魅力の一つだったのはWebSocket対応。
従来のELBではWebSocket通信を終端できなかったため、 WebSocket通信の負荷分散/バランシングを行ったりSSL/TLS化する場合、 自前でバランシングする仕組みを実装したり、Nginxを前段に配置するなどちょっとした工夫が必要だった。 AWSのLoad BalancerがWebSocketサポートしてくれるのであれば、この設計構築および運用をアウトソース出来ることになる。ハッピーな未来しか見えない。
ちょうど時間ができたので、遅ればせながら試してみた。
新しいLoad Balancer, ALBとは
至るところで紹介されているので、ここでは簡潔に。
Application Load Balancer、通称ALBは、Elastic Load Balancerのラインナップの一つという位置付けで発表された。 以前のELBは "Classic Load Balancer" という扱いになるらしい。 Management ConsoleのLoad Balancerを開くと、以下のように2つから選択できるようになっている。
主だったUpdateは以下。 魅力盛り沢山!
- Content-Based Routing (Path Based Routing):
- URLパスに基いて、リクエストを異なるバックエンドサーバに振り分けすることが出来る
- Support for Container-Based Applications:
- ECS (EC2 Container Service) - ELB 連携対応、ポートマッピングやヘルスチェック定義の運用性が大幅改善
- Better Metrics:
- ポートやURLパス (ターゲットグループ) 毎のメトリクス、トラフィック(GB)、アクティブコネクション数、コネクションレートなどメトリクスを拡充
- Support for Additional Protocols & Workloads:
- WebSocketとHTTP/2 をサポート
引用: Amazon Web Services ブログ (日本語)
WebSocketとLoadBalancer
これまでのWebSocketアプリケーションの構成
おさらい。
詳しくは以前の記事に記載しているが、従来のELBではWebSocket通信をサポートしていなかったため、 WebSocket通信の負荷分散/バランシングを行うためには、自前でバランシングする仕組みを用意する必要があった。
SSL/TLS化する場合も同様。ELBで終端することが出来ないためアプリケーション側で実装したり、Nginxを前段に配置するなどちょっとした工夫が必要だった。
これからのWebSocketアプリケーションの構成
通常のWeb Applicationと同じ構成が取れる。つまりこういう事だ。
Try it!
百聞は一見にしかず。試してみる。
なお、ALBの登場に伴い、AWSのLoad Balancerの構成要素が変わったので注意。一瞬面食らうが、思想がわかれば大した差ではない。
Make Target Group
今までのバックエンドサーバの設定が Load Balancer から独立し Target Group という要素に分離された。 L7対応ということでContent-based Routingが可能になったので、Load Balancerそのものと、後段のバックエンドサーバの定義の関係性が疎になったイメージ。
ということで、まずバックエンドサーバとTarget Groupを用意する。 バックエンドサーバは、以前使ったNode.js / Socket.IOなサンプルアプリケーションを再利用し、EC2上で稼働させる。
server
package.json
How to run
$ vim app.js $ vim package.json $ vim /usr/share/nginx/html/sample.html $ npm install $ node app.js
それからTarget Groupを作成する。
基本的に今までのELBのバックエンドサーバの設定箇所と同じ。 ここで設定/作成するTarget Groupを、後ほどALBに振り分けルールとセットで登録することとなる。
- バックエンドのNode.jsサーバは :3000 で listen しているので、ProtocolはHTTP、ポートは3000を選択する
- Health Check Pathは 今回は /socket.io/socket.io.js を指定する
まず、これでTarget Groupを作成。
その後、Target GroupにInstanceを登録する。今回はテスト用に2台のEC2 instanceを用意したので、これをTarget Groupとして設定する。
ここまで特にWebSocket特有の設定項目はない。
一点注意点として、Socket.IOベースのアプリケーションを使用している場合は、Target Groupの Attribute を編集してStickness を有効化すること。 つまり、Sticky Sessionを効かせる。
理由は後述する。
Launch ALB
次に、Load Balancerを作成する。
まず、Application Load Balancer を選択する。
ALBの設定画面はいつも通り
- 名前とScheme (internet-facing か internal ) を決め、ALBのListenerとAZの設定を行う
- Listner Protocol は Target Groupと同じくHTTP / HTTPS のいずれかを選択すれば良い
HTTPSを選んだ場合は証明書を選択し、続いてSecurityGroupを選択/作成する。
ここまでは従来のELBと同じ。
次にRouting先のTarget Groupを設定する。
先程作成したTarget Groupをルーティング先として指定する。 これがデフォルトのルーティング先となる。
前述したとおり、URLパスに基づいて複数のTarget Groupを登録することも出来る。 複数のサブシステムやマイクロサービスな作りをしているものを一つのLB、ドメインでまとめたり、アプリケーションコードを変えずにALBだけでパスルーティングを返ることが出来たり、 運用が幸せになる可能性を感じる。
設定内容が問題ないことを確認後、ALBを立ち上げる。
これだけ。 WebSocket特有の設定項目は必要ない。
Run!
このLoad Balancer経由でサンプルアプリケーションを稼働させる。
以下の sample.html を手元のPCで作成し、ブラウザで開くとサンプルアプリケーションが立ち上がる。
ブラウザのDeveloper ConsoleなどでHTTP Upgrade (101) やWebSocketの通信状況を確認して、無事接続確立していればOK。
心配になるくらい、驚くほどあっさり動いてしまう。
Socket,IO 利用時の注意点
前述したが、Socket.IOを利用しているWebSocketアプリケーションの場合、Sticknessを有効化しておく必要がある。 これはSocket.IOのハンドシェイク処理の仕様で、接続確立までに行われる幾つかのHTTPリクエストが同一サーバに固定される必要がある。 公式ドキュメントにも言及されている。
Socket.IO — Using multiple nodes
Sticknessが無効のままだと以下のように400エラーや502エラーが発生し、接続確立に失敗する。
この時のResponse Dataを見てみると、前リクエストでSession ID が見つからない旨出力される。
{"code":1,"message":"Session ID unknown"}
シンプルにWebSocketを話すアプリケーションは特にSticknessの有効化は不要だと思うが、 環境やブラウザによってはWebSocketを話せないケースもあるため、両方に対応可能なSocket.IOを利用するケースは多いと思うので、参考までに。
所感
何度も言うが、心配になるくらい、驚くほどあっさり動いてしまう。 簡単なチャットアプリケーションであれば、ALB前段にかませばそれで終了だ。
WebSocket接続用のEndpointの管理が不要となり、DNS Recordのメンテは初回以降不要。 SSL/TLS通信の終端先としても使えるのでReverseProxyを置く必要もなくなる。 Target GroupにAutoScaling Groupの登録もできるようなので、普通のWebアプリケーションサーバと同じ感覚でScalingできるようになる。
WebSocketアプリケーションの作りや規模によってはシャーディングっぽい作りが必要になることもあると思うが、 その際はTarget GroupとPath Rule追加して、同じALBにぶら下げれば良い。
ALBを活用すればランニングコスト、構築や運用にかかる労力ともに減るので、メリットしか感じられない。
がしがし活用していこう。