Windows Azure Web サイトでは既定で ARRAffinity という名前のクッキーを発行して、セッションアフィニティを行っています。
Web サイトが行っている ARR を使ったセッションアフィニティについては以下の記事を参考にしてください。ちなみに、これは ARR に用意されている機能が普通に使われています。
セッションアフィニティは WebSocket の時にも同様に行われていると思われます。
ちゃんと Upgrade リクエストに ARRAffinity クッキーが送信されていることが分かりますね。今回はこのセッションアフィニティが WebSocket 利用時にどのように影響を与えるのかを調べてみました。
WebSocket の接続が確立された時のインスタンス名を知りたいので、SignalR で以下のような Hub を用意してテストしてみました。
[HubName("echo")] public class EchoHub : Hub { public string Send() { return Environment.MachineName; } }
単純に MachineName を返すだけだと分かりにくかったので、実際には接続数の表示も付けてあります。
実際に共有モードで 2 インスタンスを立ち上げている Web サイトにデプロイして、共有モードの限界である 35 接続までコネクションを開いたところです。
同じブラウザで 35 接続まで確立しましたが、セッションアフィニティが効いているからか、今までも検証してきている Web サイトの特性なのか、全く他のインスタンスには振られることはありません。
この ARR の挙動に関しては、以下の記事も参考にしてください。
この状態で 36 接続目を確立すると、同じインスタンスにそのまま繋がり、WebSocket から Server-Sent Events にトランスポートが切り替わってしまいました。これは以前検証した結果通りですね。
少しだけ WebSocket の場合は接続上限数に達した段階で、別のインスタンスに振られるんじゃないかと期待しましたが、そんなことは無いみたいです。
確かに WebSocket を使っている場合には、均等にリクエストが振られるよりも余裕がある場合 1 インスタンスに集中したほうが効率が良いですが、これだとわざわざ非効率な通信を使っている感じで微妙な気がしてきますね。
やっぱり Web サイトでは複数インスタンスを予約するよりも、オートスケールに頼った運用を行った方が全体的な使用リソースが最適化されると思います。