Socket.io: ELBの背後にあるAWSEC2は常にエラーを出力します予期しない応答コード:400

作成日 2014年10月30日  ·  66コメント  ·  ソース: socketio/socket.io

やあみんな-

これに対する解決策を見つけることができないようですが、ロードバランサーの背後でアプリを実行すると、クライアントで次のエラーが発生します。

WebSocket connection to 'wss://fakedomain.com/socket.io/?EIO=3&transport=websocket&sid=QH8VmXbiEcp3ZyiLAAAD' failed: Error during WebSocket handshake: Unexpected response code: 400 

ロードバランサーとEC2インスタンス(AWSは得意ではないので、気軽にサポートを提供してください!)と通信しようとしているため、エラーは理解できますが、理解できないのは、エラーが表示されません!

根本的な原因を修正したいのですが、現時点では時間がないすべてのリアルタイムのものを処理するために、別の専用のsocket.ioサーバーが必要だと思いますが、誰かが私を抑制して実行してくださいこのエラー?

ポーリングにフォールバックしていると思いますが、これは問題なく機能しているようです(ソケット接続が接続されていて、起動します)が、コンソールで赤いエラーが発生して起動したくありません。

あなたが持っているかもしれないどんなアドバイスにも前もって感謝します!

最も参考になるコメント

Elastic Beanstalkを使用していないと思います(手順ははるかに簡単です)。

EC2->ネットワークとセキュリティ->ロードバランサーに移動します

ロードバランサーを選択し、リスナーに移動します。 ロードバランサプロトコルとインスタンスプロトコルの両方が、HTTPとHTTPSではなく、ポート80ではTCPに、ポート443ではSSLに設定されていることを確認します。

全てのコメント66件

また、重要な場合は、bowerを介してインストールしました。

"socket.io-client": "〜1.1.0"、

サーバーにスティッキー接続がありますか?

Elastic Beanstalkを使用していないと思います(手順ははるかに簡単です)。

EC2->ネットワークとセキュリティ->ロードバランサーに移動します

ロードバランサーを選択し、リスナーに移動します。 ロードバランサプロトコルとインスタンスプロトコルの両方が、HTTPとHTTPSではなく、ポート80ではTCPに、ポート443ではSSLに設定されていることを確認します。

ちょっと、あなた。 これは私が他では見たことがない確かなアドバイスです。 午前中にやってみます
報告してください。 ありがとう!

水曜日、2014年10月29日には、午前7時48分PMヴァディムKazakov [email protected]
書きました:

Elastic Beanstalkを使用していないと思います(そこにある手順は
はるかに簡単になります)。

EC2->ネットワークとセキュリティ->ロードバランサーに移動します

ロードバランサーを選択し、リスナーに移動します。 両方の負荷を確認します
バランサープロトコルとインスタンスプロトコルは、ポート80と
HTTPおよびHTTPSではなくポート443のSSL。


このメールに直接返信するか、GitHubで表示してください
https://github.com/Automattic/socket.io/issues/1846#issuecomment -61038664

間違っているかもしれませんが、私たちのサイトはHTTPSで実行されています(SSL証明書を使用)。 それらを変更して、多くのものを壊してしまいます。 アプリでX-Forwarded-Protoをチェックして、リクエストがHTTPSであることを確認し、そうでない場合は、リダイレクトを強制しました。 どうやらSSL / TCPのX-Forwarded-Protoヘッダーはなく、Expressはreq.secureをfalseとして報告しています(httpsと入力した場合でも)。

提案?

確かではありませんが、ソケットはHTTPではなくTCP / SSLプロトコルを使用しているため、Webソケットを機能させるにはTCP / SSLに変更する必要があります。 アプリの残りの部分を修正する方法については、私にはわかりません。

助けてくれてありがとう。 私は新しい環境を作り、少し混乱する必要があります。 機械にはたくさんの歯車があります!

WebSocketを独自のポートで実行することは可能ですか? もしそうなら、あなたはいくつかのドキュメントをリンクできますか? (ないことは確かですが、間違っている可能性があります)

ポートを接続するタイミングを次のように指定するだけで、必要なポートで動作できます。

io('https://myserver:123');

Elasticbeanstalkを使用していますが、同じ問題に直面しています。SSLはインストールされていませんが、通常のhttpを介して接続されています。

こんにちは、
SockJSを使用していますが、同じ問題が発生します。
私のアプリケーションはJavaSpring 4アプリケーションであり、開発マシンで動作し、
AWSでも同じエラーが発生します。
アップグレードヘッダーが誰かによって削除されているようです。クライアントで確認できます。

まだ解決策を見つけることができます...

私は同じボートに乗っており、AWSエンジニアとのライブチャットを行っていますが、どちらも困惑しています。 ELBをHTTP / HTTPSからTCP(またはSSL(Secure TCP))に変更する必要があることを確認しましたが、それでも400エラーが頻繁に発生します。 Elastic Beanstalk負荷分散クラスターに移行するまで、この問題は発生しませんでした。

app.useミドルウェアのもの(ヘッダー/コード関連)がある場合はコメントしてみてください。またはapp.get( "/"で、どちらがうまくいったかわかりませんが、結果を投稿してください。

更新:それがELBであることを確認しました。これは、HTTPまたはHTTPSトラフィック用に構成されているかどうかに関係なく、socket.ioが失敗します。 EC2の1つに直接行くと、すべてがうまく機能します。

添付されているのは、ELBを通過するときに私が見ているものです。
snipimage

ロードバランサーの前にRoute53インスタンスを追加することで、問題を解決したようです。
AWS環境で安全な接続を備えたWebSocketが機能するようになりました。

Route 53を追加してみてください。これで問題が解決しない場合は、設定を共有させていただきます。

@ yoav200は、何があなたのためにうまくいったのかについて、あなたの構成全体を共有できると思いますか? つまり、EBSセキュリティ+プロトコル(http / tcp)のポート、必要な.ebextensionsなどです。nginx構成をハッキングしてアップグレードヘッダーを保持し、ノードに送信するためにさまざまなことを試みましたが、何も機能しませんでした。 FWIW-wikiページはこれに本当に本当に役立ちます。 動作したのは、EC2インスタンスに直接接続することだけでした。

ドメインを管理するRoute53インスタンスを設定しました。
ドメインをロードバランサーに直接ポイントするレコードを使用してホストゾーンを構成しました。

ロードバランサーは、次に示すように、Tomcatインスタンスにリクエストを転送するように構成されています。
lb-listeners

ELBのセキュリティグループはかなり標準的です。
lb-security-group

nginxを使用していますか? 構成に関して特別なことをする必要がありましたか?

私はこれが機能するようになり、過去2日間でAWSサポートエンジニアとほぼ8時間過ごしました。 ミックスからnginxをリッピングする必要がありましたが、非常に接近しており、ソケットはhttpを介してELBを介して正常に機能しています。明日は、ELBレベルではなくサーバー側でhttpsのものを処理できると思います。

調査結果を報告します。

私はnginxを使用していません。すべてをアマゾンで管理しています。ドメインもアマゾンに移動しました。
ただし、インスタンスにAWSを使用するホスト型クラウド環境からアプリケーションを移行しましたが、nginxで負荷を管理しており、問題はありませんでした。

それが彼らのためにどのように機能しているかを彼らに尋ねられたとき、彼らの応答は次のとおりでした:

Amazon Elastic Load Balancerは使用せず、独自のNGinxロードバランシングレイヤーを使用します。
解決策は、ELBの代わりにNginxまたはHAProxyサーバーを使用し、haproxy / nginxの1つのノードで自動スケーリンググループを使用して、コンポーネントの高可用性を確保することです。

ええ、私はHAProxyが別のオプションであると言われましたが、私はそれが一日の終わりまでに次のサービスで動作することを確信しています:

  • 弾性ビーンズトーク
  • ELB
  • EC2 Autoscalingグループ(EBによって作成)
  • RDS
  • ElastiCache

ノードアプリは現在これらすべてのサービスで動作していますが、私が言ったように、HTTP経由でのみ、本番環境の準備をするためにやるべきことはあまり残っていません。 後で調査結果/構成を報告します。

@niczakは、これがどのように機能しているかを少し共有できますか?

現在、ElastiCacheのRedisを使用して、EC2のノードインスタンスでSocket.IOに接続しようとしています。

ソケットに簡単に接続できるように、EC2インスタンスを公開し、パブリックIPアドレスで応答しました(http://coding-ceo.ghost.io/how-to-run-socket-io-behind -elb-on-aws /)。 ELBでスティッキーセッションを使用していますが(これが接続されたままになることを期待しています)、ソケットはまだ接続されず、ハンドシェイク応答を受信する前に接続が閉じられました。

ポーリングは正常に機能しますが、ソケットとパス全体を正常に機能させようとします。

かなり長い間頭を悩ませてきたので、インスタンスを適切に構成できるように(httpやhttpsではなくHTTPのみである場合でも)、ここでユースケースを確認したいと思います。

手伝ってくれてどうもありがとう!

@petrogad

ねえピート!

私のELBリスナーは可能な限りシンプルで(画像を参照)、デフォルトではEC2ポート80でiptablesを使用して8080に転送されます。 そうは言っても、HTTPSでサーバーにアクセスすると、ノードアプリは8080でリッスンし、SSL証明書自体を提供します。

elb

証明書を処理するためのノードコードは次のとおりです。

        files = ["COMODOHigh-AssuranceSecureServerCA.crt", "AddTrustExternalCARoot.crt"];
        ca = (function() {
            var _i, _len, _results;
            _results = [];
            for (_i = 0, _len = files.length; _i < _len; _i++) {
                file = files[_i];
                _results.push(fs.readFileSync('/etc/ssl/tcerts/' + file));
            }
            return _results;
            })();

        httpsOptions = {
            ca: ca,
            key: fs.readFileSync('/etc/ssl/tcerts/multidomain.key', 'utf8'),
            cert: fs.readFileSync('/etc/ssl/tcerts/14432575.crt', 'utf8')
        };

        this.serverPort = 8080;
        var httpsServer = https.createServer(httpsOptions, apiInstance);
        httpsServer.listen(this.serverPort);
        startSockets(httpsServer);

Webソケットが(長いポーリングにフォールバックせずに)機能するために、クロスゾーン負荷分散を無効にする必要がありました。 残念ながら、AWSはELBを介してWebソケットをサポートするとは主張していないため、これらのタイプの構成の「ハック」が必要です。 うまくいけば、これはあなたを立ち上げて実行するのに十分でしょう!

ありがとう@niczak

すべてが完全に機能しており、HTTPトラフィックが発生し、問題が発生していました。 また、複数のインスタンスでredisが機能するようになりました。 最後に、reClusterで作業し、tcpルートを特定のワーカーに固定できるようにします。

これで多くの成功を収めましたか? Expressを使用しているため、スティッキーセッションがうまく機能していません。 運が良かったですか?

もう一度感謝します。これがすべて完了したら、同様のアイテムで苦労している他の人のために、素敵なブログ投稿を入手できることを願っています。

ありがとう@niczak !!

私はついに私の仕事も始めました。 ただし、構成に加えて
1)TCPプロトコルを使用するロードバランサー
2)クロスゾーン負荷分散を無効にするロードバランサー

私も設定する必要があります
3)[ソフトウェア構成]セクションでプロキシサーバーを「なし」にします。

screen shot 2015-01-09 at 10 28 56 am

これは素晴らしいニュースです@aidanbon@ petrogad 、AWSのソケットの万歳! :+1:

どうもありがとう! それは弾力性のある豆の木に関する私の問題を解決しました。 nginxプロキシを削除することは理にかなっています

私の元の投稿からの更新:

HTTPSをSSL(443 --->カスタムポート)に変更し、HTTP(80 --->カスタムポート)のままにしました。

エクスプレス!req.secure && X-Forwarded-Proto!=== httpsでチェックしていたコードがあり、ポート80にアクセスするとHTTPSにリダイレクトされます...

でも

SSLに変更すると、X-Forwarded-Protoが未定義に戻ります....この接続を切断します。 (また、req.secureは非推奨になる可能性があるようです)

だから今:

if (req.get('X-Forwarded-Proto') === 'http') {
            res.redirect('https://' + req.get('Host') + req.url);
        }

うまく機能しているようで、コンソールに400エラーが表示されなくなりました。

Hullo-Elastic BeanstalkでNode、NGINX、SSL、およびELBを使用してこれを機能させ、次のことを実行しました。

.ebextensionsにcontainerコマンドを作成して、プロキシWebSocketを含めるようにnginx構成スクリプトを変更します。

container_commands:
    00proxy:
        command: sed -i 's/proxy_http_version.*/proxy_http_version\ 1.1\;\n\ \ \ \ \ \ \ \ proxy_set_header\ \ \ \ \ \ \ \ Upgrade\ \ \ \ \ \ \ \ \ \$http_upgrade\;\n\ \ \ \ \ \ \ \ proxy_set_header\ \ \ \ \ \ \ \ Connection\ \ \ \ \ \ \"upgrade\"\;/g' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf

Elastic Beanstalk Webコンソールを使用して、SSL証明書をロードバランサーにインストールします。

次に、EC2 Webコンソールに移動し、SSL 443-> TCP80でリッスンするようにロードバランサーを変更します。EBWebコンソールで変更した場合、これは機能しませんでした。EC2で直接行う必要がありました。

これですべてが機能するはずです。 リダイレクトを行う必要はなく、NGINXも機能させることができました。

@ChrisEdsonこのソリューションを使用するためにパッケージに含めるものは他にありますか?
試してみましたが、エラーが原因で展開に失敗しました。 ログには次の行が表示されます。

/etc/init.conf: Unable to load configuration: No such file or directory

コードを投稿できますか?

13:13時金、2015年9月4日には、Treyone [email protected]書きました:

@ChrisEdsonこのソリューションを使用するためにパッケージに含めるものは他にありますか?
試してみましたが、エラーが原因で展開に失敗しました。 ログには次の行が表示されます。

/etc/init.conf: Unable to load configuration: No such file or directory

このメールに直接返信するか、GitHubで表示してください。
https://github.com/socketio/socket.io/issues/1846#issuecomment -137718880

アプリのコードは非常に基本的なsocket.ioの実装であり、ほとんどすぐに使用できる例です。
追加したのは、.ebextensionsの.configファイルだけです。このファイルには、前に引用したコードスニペットをコピーしました。
だから私は投稿することがあまりありません:)

心配しないでください。コードやログなしでデバッグするのは難しいだけです。 ログを投稿できますか? おそらくここに固執するのは適切ではないでしょう、多分それらをペーストビンに入れてください。

15:26時金、2015年9月4日には、Treyone [email protected]書きました:

アプリのコードは非常に基本的なsocket.ioの実装であり、ほとんどすぐに使用できる例です。
追加したのは、.ebextensionsの.configファイルだけです。このファイルには、前に引用したコードスニペットをコピーしました。

だから私は投稿することがあまりありません:)

このメールに直接返信するか、GitHubで表示してください。
https://github.com/socketio/socket.io/issues/1846#issuecomment -137749890

ふむ、私は手動パッケージの代わりにうなり声でコードを公開しました、そしてそれは魅力のように機能します。 自動化は必須です;)

それを聞いてうれしい!

15:14で火、2015年9月8日には、Treyone [email protected]書きました:

ふむ、私は手動パッケージの代わりにうなり声でコードを公開しました、そしてそれは魅力のように機能します。 自動化は必須です;)

このメールに直接返信するか、GitHubで表示してください。
https://github.com/socketio/socket.io/issues/1846#issuecomment -138572724

私の日を救え!

この基本的な問題も見ました。 基本的に、SocketIOはWebSocket接続を確立するために2つの要求を送信するため、これらの呼び出しがインスタンス間でフェデレーションされると、セッションIDが認識されず、ハンドシェイクが失敗し、SocketIOがロングポーリングにフォールバックします。 これは、wsまたはwssを使用しているかどうかに関係なく当てはまります。 レイヤー7(HTTP)の負荷分散をWebSocketで機能させることができなかったため、レイヤー4(TCP)で負荷分散を設定したことを前提としています。

修正は、スティッキーセッションを有効にして、呼び出しがインスタンスに渡されると、ロードバランサーがそれらのリクエストを同じインスタンスに送信し続けるようにすることです。 ただし、AWSのELBを使用している場合、レイヤー4の負荷分散にスティッキーセッションを使用することはできません。

最終的には、SocketIOではなく生のWebSocketを使用しました。これは、呼び出し間で永続化する必要のあるセッションデータがないためです(1回の呼び出し、ハンドシェイクが行われ、それが機能します)。

AWS側の修正は、スティッキーセッションをレイヤー4の負荷分散に何らかの方法で使用できるようにすることです。

SocketIOの部分の修正は、WebSocketハンドシェイクが前のsessionIDのコンテキストを必要としないようにすることです(これに関する目的やライフサイクルはわかりません。これは、長時間のポーリングとその他の両方に役立つと想定しています。接続が終了した場合はすぐに再接続します。クライアントが接続が切断されたと判断した場合、接続がすでに存在すると信じていたためにバックエンドがハンドシェイクを拒否するのではなく、新しいセッションを生成して正常に再接続できます)。

潜在的な修正は、Redisを使用して、すべてのインスタンスにわたってセッション状態を永続化することです。 私はこれをテストしていません。

負荷が許せば、回避策は、アベイラビリティーゾーンごとに単一のノードインスタンスのみを確保し、ゾーン間の負荷分散を無効にすることです。 そうすれば、すべての呼び出しがデフォルトで単一ノードになり、この問題を回避できます。

@aidanbon Proxy server to be "none" in the Software Configuration section見つかりません

私は単にubuntuサーバーとmupデプロイメントでMeteorJSを使用しています..リンクを教えていただけませんか?

乾杯

@sahanDissanayake次の方法でプロキシサーバーの構成オプションを見つけました。

  1. 対象の環境で「構成」をクリックします
  2. 構成ページ内から「ソフトウェア構成」をクリックします
  3. 前のスクリーンショットに示されている「プロキシサーバー」ドロップダウン。

注:私の環境はほぼ1年前にプロビジョニングされました。 AWSパネルが新しい環境用に更新されているかどうかはわかりません。 ただし、今日でもこのドロップダウンを自分の環境で見ることができます。

@aidanbon ec2以外のサービスは使用していません。そのため、設定は私には関係ありませんか?または、このpoxyサーバーの使用を開始する必要がありますか?

したがって、私が抱えている問題は、私のWebアプリのWebSocketはポート8080で機能しますが、ポート80では機能しないということです。

これが問題です

@lostcolonyまとめありがとうございます。 私は同じ結論に達しました。 このブログ投稿を読んだことがあります: https ://medium.com/@Philmod/load -balancing-websockets-on-ec2-1da94584a5e9#.hd2ectz8t? 彼は基本的に、レイヤー4(TCP)をHAProxyインスタンスに渡すことができ、HAProxyインスタンスは、PROXYヘッダーを削除し、スティッキーセッションを使用してトラフィックを適切なインスタンスにルーティングできると言っています。 ただし、2つのHAProxyが「バックエンド」サーバーリストをどのように構成し、どこで実行し、実際のsocket.ioサーバーをどこで実行するかはわかりません。 あなたはそれを理解できますか?

編集:私は今クリックしたと思います。 彼は既知のサーバーのセットを持っていて、自動スケーリングを気にしないので、リストを知っています...

サーバーリストは、各HAproxyボックスで構成されます。 方法がわかりません
いくつか書いた場合を除いて、自動スケーリングec2インスタンスでそれを機能させるため
新しいサーバーが来たときにそのリストを更新するための追加のインフラストラクチャ
オンライン。 Socket.ioは、Webアプリと同じサーバーで実行されているため、
接続はElbを介して着信し、HAproxyインスタンスにフェデレーションされます。
HAproxyインスタンスは、IP接続が常に同じになるようにします
socket.ioがセットアップされた場所であるweb / appサーバー。
2016年1月13日午前2時50分、「FelixSchlitter」 [email protected]は次のように書いています。

@lostcolonyhttps ://github.com/lostcolony要約をありがとうございます。 私
同じ結論に達しました。 このブログ投稿を読んだことがありますか:
https://medium.com/@Philmod/load -balancing-websockets-on-ec2-1da94584a5e9#.hd2ectz8t?
彼は本質的に、レイヤー4(TCP)を
HAProxyインスタンスは、PROXYヘッダーを削除し、
スティッキーセッションを使用して適切なインスタンスにトラフィックします。 しかし、そうではありません
2つのHAProxyが「バックエンド」サーバーリストを取得する方法は明らかです
構成済み、実行場所、および実際のsocket.ioサーバーの実行場所。
あなたはそれを理解できますか?


このメールに直接返信するか、GitHubで表示してください
https://github.com/socketio/socket.io/issues/1846#issuecomment -171208211

@lostcolony OK、HAProxyを使用したamazonでの自動スケーリングに関して興味深いプロジェクトがあることを確認しました少なくとも参照には役立ちます: //github.com/markcaudill/haproxy-autoscale。 私が得られないのは、なぜHAProxyの前でELBを使用するのですか? HAProxyインスタンスは1つだけである必要があります。そうでない場合、ELBがトラフィックを適切なHAProxyインスタンスに送信することをどのように保証しますか? 彼ら(HAProxyインスタンス)がElastiCacheやRedisなどを使用して共通のスティッキーテーブルを共有していない限り、それらの線に沿って? ...私たちはトピックから「道を外れる」ことを理解しています。

IPに基づいて接続をルーティングするようにHAProxiesを構成している場合
同じインスタンスで終わることを保証できます。 つまり、HAProxiesの場合
ip ABCDはインスタンス1に向けられるという同じルールがあり、
次に、ELBがヒットしたHAProxyに関係なく、同じ結果になります
場所。 それはあなたが送ったそのリンクで起こっていることです、彼らはバランスを取っています
ソース経由、つまりHAProxyインスタンスがIPをハッシュし、それを使用して
どのインスタンスに移動するかを決定します。 複数のHAプロキシ(すべての場合)
同じインスタンスについて知っているので、1つの場所からにトラフィックを送信します
同じバックエンドインスタンス。

13:19の水曜日、2016年1月13日には、フェリックスSchlitter [email protected]
書きました:

@lostcolony https://github.com/lostcolony OK、
HAProxyを使用したamazonでの自動スケーリングに関する興味深いプロジェクト-
少なくとも参照に役立ちます:
https://github.com/markcaudill/haproxy-autoscale。 私が得られないのはなぜですか
HAProxyの前でELBを使用しますか? HAProxyインスタンスは1つだけである必要があります。
それ以外の場合、ELBがトラフィックを右側に送信することをどのように保証しますか
HAProxyインスタンス? それら(HAProxyインスタンス)が共通を共有していない限り
どういうわけかElastiCacheやRedisなどを使用したスティッキーテーブル
行? ...私たちはトピックから「道を外れる」ことを理解しています。


このメールに直接返信するか、GitHubで表示してください
https://github.com/socketio/socket.io/issues/1846#issuecomment -171386260

@lostcolonyハッシュは特定のIPに対して決定論的に導出されることを理解していますが、「ハッシュ->インスタンス」のマッピングが必要です。 あなたの場合、「ABCDはインスタンス1に向けられている」というルールがあると言っていますが、利用可能なサーバーのリストを前提として、HAProxyがどこにリダイレクトするかを自分で決定したくないですか? 結局のところ、「ABCD」は単なるクライアントのIPであり、事前にはわかりません。

ハッシュをインスタンスにマッピングするためのルールは、すべてのHAProxyで同じです。
インスタンス。 つまり、ABCDは、
ヒットしたHAProxyインスタンス、およびそのハッシュは同じサーバーにマップされます。
すべてのHAProxyが知っている場合は、使用中のHAProxyインスタンスに関係ありません。
同じインスタンス(そしておそらく同じ順序/同じ名前)。 ザ
実際のIPは重要ではないため、事前に知る必要はありません。
どのIPも、通過するHAProxyに関係なく、同じサーバーにハッシュされます。
終えた。

完全に偽造された例の場合(HAProxyはそうではないものを使用します
予測可能です、私は確信しています)、構成されている3つのサーバーがあったと想像してください
server0、server1、serve2の順に(実際の詳細は関係ありませんが、
明確な順序があるというだけで、暗黙的には問題ありません)。 すべてのHAProxy
インスタンスには、同じサーバーが同じ順序であります。 彼らも同じです
着信IPアドレスの処理方法に関するルール。 この些細な例では、
アドレスの4つの部分すべてを整数として合計します(簡単に拡張できます
IPv6をサポートし、すべてを16進数として基数10)に加算し、3で除算します。
残り。 したがって、IP 123.12.61.24 =(123 + 12 + 61 + 24)%3、または1です。したがって、ルーティングされます
server1へ。 つまり、どのHAProxyインスタンスに入っても、それは
接続はserver1に送信されます。

これで、server1がオフラインになると、アルゴリズムはすべてのHAProxyで変更されます
インスタンス、すべてのパーツを追加するには、モジュラス2。

そして、これは一般的に機能します-ネットスプリットを取得しない限り(または
別のサーバーリストを持つHAProxyインスタンス)。 1つのHAProxyが見る場所
3つのインスタンス、もう1つは2を参照します。その場合、保証はできません。
同じバックエンドに到達します。 そして確かに、それは問題になる可能性があります。 しかし
それがリンクで説明されている解決策です。

15:51の水曜日、2016年1月13日には、フェリックスSchlitter [email protected]
書きました:

@lostcolonyhttps ://github.com/lostcolonyハッシュが
特定のIPに対して決定論的に導出されますが、マッピングが必要です。
「ハッシュ->インスタンス」の。 あなたの場合、あなたは次のようなルールがあると言っています
「ABCDはインスタンス1に向けられています」と言っていますが、
利用可能なリストを指定して、リダイレクト先を決定するHAProxy
サーバー? 結局のところ、「ABCD」は単なるクライアントのIPであり、知られていない
フロント。


このメールに直接返信するか、GitHubで表示してください
https://github.com/socketio/socket.io/issues/1846#issuecomment -171428465

Elastic Beanstalkで、WebインターフェイスでTCPとSSLを使用するようにロードバランサーを設定したにもかかわらず、ロードバランサーの構成を直接確認したところ、セキュアリスナーにHTTPSを使用していることがわかりました。 したがって、EC2>ロードバランサーセクションで、ポートが適切に設定されていることを確認する必要があります。

screen shot 2016-03-08 at 16 08 34

それがソートされたら、以下を.ebextensionsに追加すると、すべてうまくいきます:)

container_commands:
  01_nginx_static:
    command: |
      sed -i '/\s*proxy_set_header\s*Connection/c \
              proxy_set_header Upgrade $http_upgrade;\
              proxy_set_header Connection "upgrade";\
          ' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf

ただし、スティッキーセッションのサポートはTCPを介して機能しないため、これはインスタンスが1つしかない場合にのみ100%機能します。

@ lostcolony@ williamcoatesの投稿は、説明をありがとうと私に思い出させました。 私がそれをするのを忘れたなんて信じられない。 ご説明は大変参考になりましたので、お時間を割いていただきありがとうございます。

そのため、同じ問題が発生し、HTTPSを使用するようにECBを設定したことがわかりました。
HTTPSをSSLに変更しましたが、メッセージが表示されなくなりました。
したがって、HTTP / HTTPSではなく、TCP / SSLを使用してください

2016年8月の時点で、「クラシック」ELBの代わりにAmazonのApplication Load Balancer(ALB)を使用できます。 HTTP80およびHTTPS443のリスナーを使用して、「箱から出してすぐに」動作しました。

@ trans1t甘い男、情報をありがとう! 私はそれをチェックする必要があります。

@ niczak-ソケットトラフィックの粘着性のためにALBにも切り替えました。 ただし、最初はALB Sticky Sessionsの構成に苦労しました(このテーマに関するドキュメントがあまりなかったため、少なくとも数か月前)。 最後にそれを理解してもらいます。 重要なのは、「スティッキネスはターゲットグループレベルで定義される」ということです。したがって、トラフィックを処理するターゲットグループを作成してから、スティッキネスを追加してください。

@aidanbonそれは素晴らしい情報です、共有してくれてありがとう!

AWS Application Load Balancerでまだ問題が発生している場合は、セキュリティポリシーを更新してみてください。別のウェブサイトの正確なセットアップでは完全に正常に機能していましたが、セキュリティポリシーが約1年遅れていることに気付きました。 新しいものに更新することで問題は解決したようです。

@michaelmitchell何か変更しましたか、それとも変更せずに更新しましたか?

アプリケーションで何も変更しませんでした。新しいポリシーに変更した後は機能していないように見えたため、ALBでHTTPSリスナーを削除して再度追加するだけでした。

ただし、セキュリティポリシーを更新した後でもエラーが表示されるのは、ブラウザセッションが古いセキュリティポリシーを保持している可能性が高いため、リスナーの追加/再追加が本当に必要かどうかはわかりませんが、シークレットモードで開くと正常に機能しました。すべてのクロームセッションを閉じて再度開くと正常に機能し、それ以降は表示されていません。

知ってよかった、ありがとう!

Leven。 31の火星2017 12:02à、マイケル・ミッチェル[email protected] A
écrit:

アプリケーションで何も変更しませんでした。追加の手順は1つだけです。
後のように、ALBでHTTPSリスナーを削除して再度追加する必要がありました
新しいポリシーへの変更は機能していないようです。

しかし、セキュリティを更新した後でもエラーが表示されることを学びました
ポリシーは、古いセキュリティポリシーを保持しているブラウザセッションである可能性があります
そのため、リスナーの追加/再追加が本当に必要かどうかはわかりませんが、
シークレットモードを開くと正常に機能し、すべてのChromeセッションを閉じた後
そしてそれを再開することはうまくいき、それ以来それを見ていません。


コメントしたのでこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/socketio/socket.io/issues/1846#issuecomment-290672158
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/ADrIi_SXqccWOLUMIWF1IhClGXvKAGMcks5rrM8sgaJpZM4C0swP

このスレッドは、AWS /socket.ioの問題を理解するための場所になったようです—

私の設定では、クライアントは、socket.io接続のデータを使用してHTTPS要求を行います。
HTTPSリクエストは、スティッキーセッションに必要なCookieで応答する必要があります。 問題は、socket.io接続でcookieヘッダーを渡すことができないことです。

私はこれらのリスナーでALBを使用しています:
image

これは、次のように構成された粘着性を持つターゲットグループを指します。
image

最初にHTTPSエンドポイントにアクセスしました。

fetch(`https://${url}/hub/api/spinup/${uuid}`, {
                method: 'GET',
                headers: headers,
            })

次に、ソケットを初期化します

connection = io(`wss://${url}:443/`, {
            path: `/user/${uuid}/spawn`,
        })

HTTPSリクエストがヒットするインスタンスは、ソケット接続がヒットするインスタンスである必要があります。

ソケットが確立されると(運が悪いために適切なインスタンスにヒットした場合)、ソケットはそこにとどまり、正常に機能します。問題は、WebSocketがHTTPSリクエストと同じエンドポイントにヒットすることです。

私の最初の本能は使用することです

connection = io(`wss://${url}:443/`, {
    path: `/user/${uuid}/spawn`,
    extraHeaders: {
        cookie: cookieValueFromFetchResponse
    }
})

これnodeで機能しますが、ブラウザーではcookieはXMLHTTPRequestsの禁止ヘッダーであるため、送信できません。

誰かが似たようなことをしましたか?

私は同様のことをしていませんが、ALBにはまだヘッダーベースのルーティングがありませんが、ホストベースのルーティングはあります。 これ自体は非常にハックですが、基本的には、ALBの背後にある各インスタンスが、インスタンスが認識している明示的なパスを持つようにすることができます。 その最初のHTTPリクエストが送信されると、応答の一部にパスが含まれ、WebSocketの接続にそのパスが含まれます。 つまり、HTTPリクエストはインスタンス「5」にヒットし(基準に基づいて、生成されたUUIDの方が適しています)、レスポンスの一部として「5」を返し、WebSocketはurl / 5に開かれます。 ALBには、url / 5がインスタンス5にルーティングされるというルールがあります。

自動スケーリングを使用している場合(およびインスタンスがペットではなく牛である場合)、インスタンスで実行されているコードでALB設定を変更して、適切なドメインをインスタンスにルーティングする必要があります。

詳細はこちら: https

ただし、使用しているパターンは可能な限り避けたいと思うかもしれません。 HTTPリクエストで受信されるデータは、すべてのインスタンス(DBなど)がアクセスできる方法で保存するか、確立されたらWebSocket接続を介して送信する必要があります。 現状では、HTTPリクエストとWebSocketが開く間にインスタンスが停止する可能性があり、同じ問題が発生する可能性があります(それほど頻繁ではありませんが)

@lostcolonyアドバイスに感謝します—それは間違いなく試す価値があります。

httpリクエストは、WebSocketサーバーのスピンアップをトリガーするものです(実際にはDockerコンテナー内にありますが、抽象化されています)。 接続されているインスタンスにWebSocketサーバーが存在するように、2つのリクエストを同じインスタンスにルーティングする必要があります

この行を使用すると、jupyterサーバーをエルブの後ろに配置するのに役立ちます。

service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp

誰かがawsにkubernetesを付けてこのチケットに来た場合に備えて。

HTTP2無効にするだけで、問題ありません。 ELBについて他に何もする必要はありません。

Screen Shot 2019-12-13 at 16 12 49

こんにちは、
SockJSを使用していますが、同じ問題が発生します。
私のアプリケーションはJavaSpring 4アプリケーションであり、開発マシンで動作し、
AWSでも同じエラーが発生します。
アップグレードヘッダーが誰かによって削除されているようです。クライアントで確認できます。

まだ解決策を見つけることができます...

こんにちは@ yoav200

私を救ってください。
私は同じ問題で立ち往生しています。 助けてください
WebSocketにSpringboot2.xとSockJsを使用しています
AWSにデプロイされたTomcatアプリケーションを作成しました。
従来のロードバランサーを使用した弾力性のある豆の木

今問題は
iOS開発者は接続できません。バックエンドに到達しますが、ハンドシェイク中に失敗します
以下は、CLBとALBの両方で取得したログです。


2019-12-13 15:21:22.662 DEBUG 27543 --- [nio-8080-exec-2] oswsDispatcherServlet:GET "/ wtchat / websocket"、parameters = {}
2019-12-13 15:21:22.701 DEBUG 27543 --- [nio-8080-exec-2] oswsssWebSocketHandlerMapping:org.springframework.web.socket.sockjs.supportにマップされます。 SockJsHttpRequestHandler @ 30c6a17
2019-12-13 15:21:22.714 DEBUG 27543 --- [nio-8080-exec-2] oswssthDefaultSockJsService:トランスポートリクエストの処理:GET http://mydomain.com/wtchat/websocket
2019-12-13 15:21:22.716エラー27543 --- [nio-8080-exec-2] cwcMyHandshakeHandler:無効なアップグレードヘッダーが原因でハンドシェイクが失敗しました:null

2019-12-13 15:21:22.717 DEBUG 27543 --- [nio-8080-exec-2] oswsDispatcherServlet:完了400 BAD_REQUEST

私はあなたが言ったことに従いました
image
image

ロードバランサーを直接指すルート53にレコードセットを作成しました。

これを行った後も、上記のエラーと同じようになります。

他に何をする必要がありますか?

このページは役に立ちましたか?
0 / 5 - 0 評価