Balancing)を活用し、アクセスの振り分けや負荷分散を行なうのがメジャーです。ロードバランサーを使った構成は、通常のWebシステムではごくごく一般的です。Socket.IOを使ったウェブソケット(websocket)接続では、問題となる場合があります。これには理由がありまして、私も調査に苦労しました。前提となる知識を共有しつつ、備忘録を兼ねて解説します。session)ELB(ALB)のwebsocket対応さいごにSocket.ioの仕組みをざっくりと理解するwebsocketのライブラリでSocket.ioが多用されているのは、いくつか理由があります。その大きな理由のひとつに「HTTPの仕組みを使っているため、企業のファイアウォールやセキュリティーソフトのブロックに対して耐性がある」という点が挙げられます。socket.ioロングポーリング(polling)Socket.ioでは、まずロングポーリングを使ってサーバーと接続します。ロングポーリングは、初期のLINEアプリでも採用されていた実績のある方式です。ひとことで言ってしまえば、「通常のHTTPリクエストに対するレスポンスを引き伸ばすことで、長時間の接続を維持する」のがロングポーリングです。サーバーはHTTPリクエストのレスポンスをすぐに終わらせず留保するため、クライアントとのコネクションを維持します。qiita.comロングポーリングは、一般的なHTTPリクエストの延長線上にある技術です。そのためセキュリティー制約の強い企業のファイアウォールや、セキュリティーソフトのブロックに対して強みがあります。ロングポーリングからウェブソケット(websocket)へ次にSocket.ioが実施するのは、プロトコルの昇格です。ロングポーリングは素晴らしい仕組みですが、基本的にHTTPの接続を維持できる時間には限界があります。接続が切れてしまったら再接続すれば良いのですが、これでは一定間隔で切れ目が生じてしまいます。そこで登場するのがwebsocketです。Socket.ioは「ロングポーリングからwebsocketへプロトコルを昇格(Upgrade)」しようと試みます。UpgradeHTTP/1.1にはConnectionというヘッダーがあり、コネクションのプロトコルをアップグレードすることができます。Upgrade引用:http://jxck.hatenablog.com/entry/20120725/1343174392もしコネクションのアップグレードに成功したならば、Socket.ioはウェブソケットでの通信を開始します。一方でwebsocket接続に失敗したとしても、ロングポーリングでの接続を継続することができます。このプロトコル選択の柔軟性が、Socket.ioのすごいところです。websocketが使える環境下ではwebsocketを利用し、そうでない環境下でもロングポーリングで接続を維持できます。ロードバランスされるとセッション(sid)が引き継げない問題socket.ioがウェブソケット接続を開始する場合、以下のようなリクエストを送信します。ここで注意してほしいのが「sid」という名のパラメーターです。idhttps://socket.io/docs/internals/#Upgrade「sid」とはセッションIDのことですが、ここに大きな問題があります。最初にアクセスしたサーバーと違うサーバーに振り分けられてしまった場合、発行されたセッションが見つからなくなってしまうのです。unknown」のようなエラーが発生します。最初にリクエストを送信してからウェブソケットの接続を確立するまで、常に同じサーバーにロードバランスされないと困ってしまうのです。Redisによるセッションの共有Socket.ioのセッション情報を引き継げない問題でよく選択されてきた対応策は、インメモリデータベースのRedisによるセッション情報の共有です。AWSで言うならば、Redis用のElastiCacheを使ってセッション情報を保存します。複数立っているsocket.ioサーバのセッション情報をRedisを介して共有することができるようなので、そうすれば複数のリクエストが異なるサーバに繋がっても問題なくなります。引用:https://qiita.com/shunjikonishi/items/526e6181efecf83a5f5b「socket.io-redis」というRedis向けのライブラリがあり、これを使います。2年ほど前の話ではありますが、実際に試してみたところ確かに問題ありませんでした。socketio/socket.io-redishttps://github.com/socketio/socket.io-redisElastiCacheでなく自前でRedisを用意しても構わないですが、兎にも角にもRedisが必要です。BalancerというL7のロードバランサーがあります。単なるELBとの違いがややこしいですが、OSI参照モデルで言えば最上位の第7層(アプリケーション層)でリクエストを振り分けることが可能です。session)というALBの仕組みです。スティッキーセッションを使うと、ロードバランサーのアクセスの振り分けを固定することができます。具体的な手順として、ELB(ALB)経由でサーバーにアクセスすると、HTTPレスポンスに「AWSELB」という名前のCookieが追加されます。このクッキーはALBが自動に付与する設定もできますし、手動でサーバーから追加する選択肢も可能です。ELBのスティッキーセッションはELBがサーバにリクエスト振り分ける際、特定のCookieを確認することで、特定のクライアントからのリクエストを特定のサーバに紐付けることが出来る機能です。ELBのスティッキーセッションの設定は以下3つのパターンが選択出来ますので、それぞれどのような動作となるか確認してみます。http://blog.serverworks.co.jp/tech/2017/01/05/elb-sticky/HTTPレベルの仕組みであるCookieを読み取ってアクセスを振り分けるため、高機能なアプリケーション層レベルのL7ロードバランサーであると言えます。私は、実際のスティッキーセッションを使ったsocket.ioのアクセスの振り分けは、uorat様のブログ記事を参考に行ないました。(注釈:ものすごく参考になりました。従来のELBには、websocket接続できない欠点がありました。そのためsocket.ioでwebsocket接続してるのかと思いきや、実際はロングポーリングでしたという事態が発生します。これを解消したのが、2016年8月の新機能です。なんとwebsocket対応が追加されました。これによりELBの負荷分散の恩恵を受けつつ、よりリアルタイム性の高い接続を維持することができるようになりました。WebSocketサポート:WebSocketのリクエストを受けられるようになりました。session)の活用とELB(ALB)のwebsocket対応により、Socket.ioでも通常のWebシステムと同じようにロードバランスすることができます。Cookieを使ってクライアント毎にロードバランサーの振り分け先を固定すれば良いなんて、当初は思いもしませんでした。AWSをはじめようmochikoAsTechさんの「AWSをはじめよう~AWSによる環境構築を1...2017-11-03Electronで、Web技術を使ってデスクトップアプリケーションを開発しよう!こんにちは。はてなブログProWEB系エンジニア。ブログで趣味の映画・ゲーム・読書の感想を書いたり、技術系の知見を共有しています。技術書典7にサークル参加して、技術同人誌を頒布しました。BOOTHに電子版があります。(1)月別アーカイブスポンサーリンクはてなブログをはじめよう!konosumiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。