API Gateway WebSocketのコストメリットやLambdaの同時実行数について

Amazon API GatewayでWebSocketが利用可能になりました。

使用感などは、下記のAWSブログでのチャットアプリのサンプルを構築してみると、わかってきます。それにしても、チャットアプリはWebSocketのサンプルとして定番中の定番ですねぇ…。

[発表]Amazon API GatewayでWebsocketが利用可能 | Amazon Web Services ブログ

使ってみた印象としては、「ルート」に対して、Lambda関数(あるいはその他のインテグレーション)を割り当てていく、というところが面白いところですが、それ以外の設定については、ほとんどRESTと同じだった印象です。
むしろ導入する場合のハードルは、クライアント側の実装の方かと思いました(昔socket.ioでとあるシステムを開発していたことがありますが、今もデファクトなんですかね…?)

それはさておき、本記事では、API GatewayのWebSocketを実運用する場合に、いくつか浮かんだ疑問について考えてみました。

  • ポーリング方式と比べた場合のコストメリット
  • Lambdaの同時実行数は大丈夫?
  • ALBとの比較

想定するユースケース

ユースケースとしては、チャットアプリではなく、AWS側で発生した何らかのイベントを、接続中のクライアントにプッシュする、というものです。下図の赤い矢印(サーバプッシュ)の部分の送信ですね。

f:id:jappy:20190114064014p:plain

ちなみに図中はイベントの発生元がRDSになってますが、まぁ何かしらのイベント発生だと読み替えてください。

これまでは、このようなことをやろうとした場合、

  • 同じくWebSocketをサポートしているALBを使い、EC2やLambdaなどでWebSocketサーバを立てる
  • (諦めて)クライアントからポーリングをする
  • GraphQL Subscription(使ったことない…)

などの方法がありました(参考記事 [1])

[1] リアルタイム革命/The Revolution of Real-time WebApps - Speaker Deck

ポーリング方式と比較してのコストメリット

東京リージョンの場合の料金は、2018年1月14日現在、下表のようになっています(一部のみ。無料利用枠を除く)

HTTP/REST API WebSocket API
リクエスト数に対する料金(100万回あたり) 4.25USD(最初の3億3,300万コールまで) 1.26USD(最初の10億メッセージまで)
接続時間に対する料金(100万分≒16,667時間≒694日あたり) N/A 0.315USD

ポーリングの頻度、WebSocketで送信が必要なイベントの発生頻度、接続時間、など色々と前提条件が異なるので一概に比較はできませんが、多くの場合、WebSocketの方がコストを低く抑えられそうです。

リクエスト数に対する料金は、単純計算で1/3以下になっていますし、ポーリング方式の場合、イベントの発生有無に関わらずAPIコールが発生していました。WebSocketの場合、イベントが発生していた場合だけメッセージ送信すればよいので、送受信するメッセージ数そのものも抑えることができます。

Lambdaの実行単位

当初、「クライアントとLambdaの接続が確立しっぱなしになると、クライアントの数が増えた時にLambdaの同時実行数に達してしまうのでは?」という疑問が浮かびました。1接続につき、Lambda関数が1個占有されてしまうようなイメージですね。

こちらは勘違いだったみたいです。
クライアントの接続の管理は、API Gateway側で行われます。

Lambda関数は、メッセージの送信(あるいは接続、切断)が発生した場合に限り、イベント駆動で起動され、処理が実行されるようでした。

ALBとの比較

同じくre:Inventの発表で、ALBのターゲットにLambdaが利用できるようになりました。
ALBもWebSocketをサポートしているので、ALB + Lambdaでも、イベントドリブンなWebSocketシステムの実現ができそうです。

こちらのパターンは未確認なのですが、API GatewayのWebSocketを利用するメリットとしては、スロットル制御、利用量プラン、認証、Lambda以外のインテグレーション(HTTP, Mock, その他AWSサービス)もできる、といった点だと思います。