Socket.io: AWS EC2 وراء ELB يطبع الخطأ دائمًا رمز استجابة غير متوقع: 400

تم إنشاؤها على ٣٠ أكتوبر ٢٠١٤  ·  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-> Network & Security-> Load Balancers

حدد موازن التحميل الخاص بك وانتقل إلى المستمعين. تأكد من تعيين كل من بروتوكول موازن التحميل وبروتوكول المثيل على TCP للمنفذ 80 و SSL للمنفذ 443 بدلاً من HTTP و HTTPS.

ال 66 كومينتر

أيضًا ، لقد قمت بالتثبيت عبر bower إذا كان الأمر مهمًا:

"socket.io-client": "~ 1.1.0"،

هل لديك اتصال ثابت على الخادم الخاص بك؟

أفترض أنك لا تستخدم Elastic Beanstalk (ستكون الإرشادات أسهل بكثير).

انتقل إلى EC2-> Network & Security-> Load Balancers

حدد موازن التحميل الخاص بك وانتقل إلى المستمعين. تأكد من تعيين كل من بروتوكول موازن التحميل وبروتوكول المثيل على TCP للمنفذ 80 و SSL للمنفذ 443 بدلاً من HTTP و HTTPS.

يا رجل. هذه نصيحة قوية لم أرها في مكان آخر. سأحاول في صباحا
والإبلاغ. شكرا لك!

يوم الأربعاء ، 29 أكتوبر 2014 ، الساعة 7:48 مساءً ، فاديم كازاكوف [email protected]
كتب:

أفترض أنك لا تستخدم Elastic Beanstalk (الإرشادات الموجودة هناك
يكون أسهل بكثير).

انتقل إلى EC2-> Network & Security-> Load Balancers

حدد موازن التحميل الخاص بك وانتقل إلى المستمعين. تأكد من أن كل من الحمولة
يتم تعيين بروتوكول الموازن وبروتوكول المثيل على TCP للمنفذ 80 و
SSL للمنفذ 443 بدلاً من HTTP و HTTPS.

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/Automattic/socket.io/issues/1846#issuecomment -61038664
.

لذلك ربما أكون مخطئًا ، لكن موقعنا يعمل على HTTPS (باستخدام شهادة SSL الخاصة بنا). تغييرها لكسر الكثير من الأشياء أسفل الخط. كنت أتحقق من X-Forwarded-Proto في تطبيقي للتأكد من أن الطلب كان HTTPS وإذا لم يكن كذلك ، أجبره على إعادة التوجيه. من الواضح أنه لا يوجد رأس X-Forwarded-Proto مع SSL / TCP ويبلغ Express عن req.secure بأنه خطأ (على الرغم من أنني كتبت https).

اقتراح؟

لست متأكدًا ، تستخدم المقابس بروتوكول TCP / SSL وليس HTTP ، لذا ستحتاج إلى تغييره إلى TCP / SSL من أجل جعل مآخذ الويب تعمل. فيما يتعلق بكيفية إصلاح بقية التطبيق الخاص بك ، ليس لدي أي فكرة.

شكرا للمساعدة. سأضطر إلى إنشاء بيئة جديدة والتلاعب قليلاً. هناك الكثير من التروس في الآلة!

هل من الممكن تشغيل مآخذ الويب على منافذها الخاصة؟ إذا كان الأمر كذلك ، هل يمكنك ربط بعض الوثائق؟ (أنا متأكد من أنه لا يوجد شيء ولكن قد أكون مخطئا)

يمكنهم العمل على أي منفذ تريده ، ما عليك سوى تحديده عند توصيل المنفذ كما يلي:

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

أنا أستخدم Elasticbeanstalk وأواجه نفس المشكلة ، ليس لدي SSL مثبتًا ولكنني متصل من خلال http العادي.

مرحبا،
لدي نفس المشكلة ، على الرغم من أنني أستخدم SockJS.
تطبيقي هو تطبيق Java Spring 4 ، يعمل على آلة التطوير و
الحصول على نفس الخطأ على AWS.
يبدو أنه تم إسقاط رأس الترقية بواسطة شخص ما ، يمكنني رؤيته على العميل.

يمكن أن تجد حلا بعد ...

أنا في نفس المركب وأجري محادثة مباشرة مع مهندس AWS وكلانا في حيرة من أمره. لقد أكدت أن ELB يحتاج إلى التغيير من HTTP / HTTPS إلى TCP (أو SSL (بروتوكول TCP الآمن)) ولكن ما زلت أتلقى 400 خطأ متكرر. لم تواجه هذه المشكلة أبدًا حتى الانتقال إلى مجموعة متوازنة من Elastic Beanstalk.

يرجى محاولة التعليق على أي app.use أشياء وسيطة (ذات صلة بالعناوين / cors) إن وجدت ، أو app.get ("/" ، لست متأكدًا من أي منها يناسبني ، لكن انشر نتائجك من فضلك.

تحديث: لقد أكدت أنه ELB ، سواء تم تكوينه لحركة مرور HTTP أو HTTPS ، فشل socket.io. عندما أذهب مباشرة إلى واحدة من EC2s ، كل شيء يعمل بشكل رائع.

مرفق هو ما أراه عند المرور عبر ELB.
snipimage

يبدو أنني قمت بحل مشكلتي عن طريق إضافة مثيل Route53 أمام loadbalancer.
لدي الآن مقبس ويب يعمل مع اتصالات آمنة في بيئة AWS.

حاول إضافة الطريق 53 ، إذا لم يكن هذا يحل مشكلتك ، فسيسعدني مشاركة التكوين الخاص بي.

@ yoav200 تعتقد أنه يمكنك مشاركة التكوين الخاص بك بالكامل لما يجعل الأشياء تعمل من أجلك؟ على سبيل المثال ، المنافذ على بروتوكول EBS security + (http / tcp) ، وأي امتدادات .ebextensions تحتاجها ، وما إلى ذلك ، لقد جربت العديد من الأشياء المختلفة لاختراق تكوينات nginx للاحتفاظ برؤوس الترقية وإرسالها إلى العقدة ، ولكن لم ينجح شيء بالنسبة لي . FWIW - قد تكون صفحة wiki مفيدة حقًا لذلك. الشيء الوحيد الذي نجح هو الذهاب مباشرة إلى مثيل EC2 الخاص بي.

لقد قمت بإعداد مثيل Route 53 الذي يدير نطاقي.
لقد قمت بتكوين منطقة مستضافة بسجل يوجه نطاقي مباشرة إلى موازن التحميل.

تم تكوين موازن التحميل لإعادة توجيه الطلب إلى مثيلات Tomcat الخاصة بي ، كما هو موضح هنا:
lb-listeners

مجموعة الأمان لـ ELB قياسية جدًا:
lb-security-group

هل تستخدم nginx؟ هل كان عليك القيام بأي شيء خاص من حيث التكوين؟

أنا على وشك الحصول على هذا العمل ، فقد أمضيت ما يقرب من 8 ساعات مع مهندس دعم AWS خلال اليومين الماضيين. اضطررت إلى إخراج nginx من المزيج لكنني قريب جدًا ، تعمل المقابس بشكل جيد من خلال ELB عبر http ، أعتقد غدًا أنه يمكنني التعامل مع جانب خادم عناصر https بدلاً من مستوى ELB.

سأبلغ مرة أخرى مع النتائج التي توصلت إليها.

لا أستخدم nginx ، فأنا أدير كل شيء في Amazon ، وقد قمت بنقل نطاقي إلى Amazon أيضًا ،
ومع ذلك ، فقد قمت بترحيل تطبيقي من بيئة سحابية مستضافة تستخدم AWS لمثيلاتها ولكنها تمكنت من إدارة الحمل باستخدام nginx ولم أواجه أي مشكلة هناك.

عندما سئلوا كيف يعمل لهم كان ردهم:

نحن لا نستخدم Amazon Elastic Load Balancer ، بل نستخدم طبقة موازنة تحميل NGinx الخاصة بنا.
يمكن أن يكون الحل هو استخدام خادم Nginx أو HAProxy بدلاً من ELB واستخدام مجموعة قياس تلقائي مع عقدة واحدة من haproxy / nginx لضمان التوفر العالي للمكون.

نعم ، لقد قيل لي أن HAProxy كان خيارًا آخر ولكنني متأكد تمامًا من أنني سأعمل مع الخدمات التالية بحلول نهاية اليوم:

  • شجرة الفاصولياء المرنة
  • ELB
  • مجموعة EC2 Autoscaling (تم إنشاؤها بواسطة EB)
  • RDS
  • ElastiCache

يعمل تطبيق العقدة مع جميع هذه الخدمات حاليًا ولكن كما قلت ، عبر HTTP فقط ، لذلك لم يتبق الكثير للقيام به لتجهيز الإنتاج. سأقوم بإبلاغ النتائج / التكوينات لاحقًا.

niczak ، هل ستكون قادرًا على مشاركة القليل من كيفية عمل هذا؟

الآن أحاول الاتصال بـ Socket.IO على مثيل Node الخاص بي على EC2 مع استخدام ElastiCache's Redis.

فتحت مثيل EC2 للجمهور مع الرد بعنوان IP عام حتى أتمكن من الاتصال بسهولة بالمقبس (http://coding-ceo.ghost.io/how-to-run-socket-io-behind -elb-on-aws /). على ELB الخاص بي ، أستخدم الجلسات اللاصقة (على أمل أن يظل هذا متصلاً) ، ولكن المقبس الخاص بي لا يزال غير متصل ويعطيني الفشل الجميل: تم إغلاق الاتصال قبل تلقي استجابة مصافحة.

على الرغم من ذلك ، يعمل الاقتراع بشكل جيد ، ولكن في محاولة لجعل المقابس والمسار بأكمله يعملان بشكل جيد.

أرغب في رؤية حالة استخدام هنا حتى أتمكن من تكوين المثيل الخاص بي بشكل صحيح (حتى لو كان على HTTP فقط بدلاً من http و https) لأنني كنت أقوم بتحطيم نفسي لفترة طويلة الآن.

شكرا جزيلا لكم على مساعدتكم!

تضمين التغريدة

يا بيت!

تتميز مستمعات ELB بالبساطة التي يمكن أن تكون (انظر الصورة) ويتم تحويلها افتراضيًا على منفذ EC2 80 إلى 8080 باستخدام iptables. مع ذلك ، يمكنني الوصول إلى خادمي على 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);

لكي تعمل مآخذ الويب (دون الرجوع إلى الاقتراع الطويل) ، قمت بتعطيل موازنة التحميل عبر المناطق. لسوء الحظ ، لا تدعي AWS أنها تدعم مآخذ الويب من خلال ELB ، لذا فإن هذه الأنواع من "الاختراقات" للتهيئة ضرورية. نأمل أن يكون هذا كافيًا لبدء العمل!

niczak شكرا!

كل شيء يسير على ما يرام ، حيث كانت حركة مرور HTTP مستمرة مما أدى إلى إفساد الأشياء. حصلت أيضًا على redis عبر مثيلات متعددة تعمل ؛ آخر شيء هو مجرد العمل على reCluster والسماح لمسار tcp بالالتزام بعامل معين.

هل حققت الكثير من النجاح مع هذا؟ أنا أستخدم التعبير السريع ، لذا فإن الجلسة اللاصقة لم تكن تعمل بشكل جيد. هل كان لديك أي حظ في ذلك؟

شكرًا مرة أخرى ونأمل بمجرد اكتمال كل هذا الحصول على منشور مدونة لطيف للآخرين الذين يعانون من عنصر مماثل.

شكرا niczak !!

أخيرًا حصلت على عملي أيضًا. ومع ذلك ، بالإضافة إلى تكوين
1) تحميل الموازن لاستخدام بروتوكول TCP
2) موازن التحميل لتعطيل موازنة التحميل عبر المناطق

أنا أيضا بحاجة إلى ضبط
3) يجب أن يكون الخادم الوكيل "لا شيء" في قسم تكوين البرامج.

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

هذه أخبار رائعة aidanbon و petrogad ، huzzah للمآخذ على AWS! : +1:

شكرا جزيلا! لقد حلت مشكلتي مع شجرة الفاصولياء المرنة. من المنطقي إزالة وكيل nginx

تحديث من رسالتي الأصلية:

لقد تغيرت HTTPS إلى SSL (443 ---> منفذي المخصص) وتركت HTTP (80 ---> منفذي المخصص).

لدي رمز تم التحقق منه باستخدام express! req.secure && X-Forwarded-Proto! === https الذي يعيد توجيهك إلى HTTPS إذا دخلت عبر المنفذ 80 ...

ومع ذلك

التغيير إلى SSL يجعل X-Forwarded-Proto يعود غير محدد .... قطع هذا الاتصال. (يبدو أيضًا أن req.secure قد تم إهماله)

و الآن:

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

يبدو أنه يعمل بشكل رائع ، ولم أعد أحصل على خطأ 400 في وحدة التحكم.

هالو - لقد حصلت على هذا العمل باستخدام Node و NGINX و SSL و ELB على Elastic Beanstalk للقيام بما يلي:

أنشئ أمر حاوية في .ebextensions لتعديل البرنامج النصي لتهيئة 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

قم بتثبيت شهادة SSL الخاصة بك على موازن التحميل باستخدام وحدة تحكم الويب Elastic Beanstalk.

ثم انتقل إلى وحدة تحكم الويب EC2 ، وقم بتغيير موازن التحميل للاستماع إلى SSL 443 -> TCP 80. لم يعمل هذا عندما قمت بتغييره في وحدة تحكم الويب EB ، وكان علي القيام بذلك مباشرة في EC2.

يجب أن يعمل كل شيء. لم أضطر إلى إجراء أي عمليات إعادة توجيه وتمكنت من تشغيل NGINX أيضًا.

ChrisEdson هل هناك أي شيء آخر لتضمينه في الحزمة لاستخدام هذا الحل؟
لقد حاولت ولكن النشر فشل بسبب الأخطاء. يظهر السجل خط التتابع:

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

هل يمكنك نشر الرمز الخاص بك؟

في الجمعة ، 4 سبتمبر 2015 الساعة 1:13 مساءً ، كتب 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 أساسي للغاية ، تقريبًا استخدام خارج الصندوق.
الشيء الوحيد الذي أضفته هو ملف .config في .ebextensions ، حيث قمت بنسخ مقتطف الشفرة الذي نقلته سابقًا.
لذلك ليس لدي الكثير لنشره :)

لا داعي للقلق ، من الصعب تصحيح الأخطاء بدون الرمز أو السجلات. هل يمكنك نشر السجلات؟ ربما ليس من المناسب لصقها هنا ، ربما ضعها في حاوية لصق.

في الجمعة 4 سبتمبر 2015 الساعة 3:26 مساءً ، كتب Treyone [email protected] :

كود التطبيق هو تطبيق socket.io أساسي للغاية ، تقريبًا استخدام خارج الصندوق.
الشيء الوحيد الذي أضفته هو ملف .config في .ebextensions ، حيث قمت بنسخ مقتطف الشفرة الذي نقلته سابقًا.

لذلك ليس لدي الكثير لنشره :)

قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub:
https://github.com/socketio/socket.io/issues/1846#issuecomment -137749890

يا هم ، لقد نشرت الكود الخاص بي عبر grunt بدلاً من العبوة اليدوية وهو يعمل مثل السحر. يجب أن تكون الأتمتة إلزامية ؛)

سعيد لسماعها!

في الثلاثاء ، 8 سبتمبر 2015 الساعة 3:14 مساءً ، كتب Treyone [email protected] :

يا هم ، لقد نشرت الكود الخاص بي عبر grunt بدلاً من العبوة اليدوية وهو يعمل مثل السحر. يجب أن تكون الأتمتة إلزامية ؛)

قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub:
https://github.com/socketio/socket.io/issues/1846#issuecomment -138572724

احفظ يومي!

لقد رأينا هذه المشكلة الأساسية أيضًا. بشكل أساسي ، نظرًا لأن SocketIO يرسل طلبين لإنشاء اتصال websocket ، إذا تم توحيد هذه المكالمات عبر المثيلات ، فلن يتم التعرف على معرف الجلسة وفشل الاتصال ، مما يؤدي إلى عودة SocketIO إلى الاستقصاء الطويل. هذا صحيح سواء كنت تستخدم ws أو wss ؛ يفترض أنك قمت بإعداد موازنة الحمل في الطبقة 4 (TCP) ، حيث لم أتمكن من الحصول على موازنة تحميل طبقة 7 (HTTP) للعمل مع مآخذ الويب.

سيكون الإصلاح لتمكين الجلسات الثابتة ، بحيث يستمر موازن التحميل في إرسال هذه الطلبات إلى نفس الحالة بمجرد انتقال المكالمة إلى مثيل ؛ ومع ذلك ، إذا كنت تستخدم AWS 'ELBs ، فإنها لا تسمح لك باستخدام الجلسات اللاصقة لموازنة حمل الطبقة 4.

ما فعلناه في النهاية هو استخدام مآخذ ويب أولية ، بدلاً من SocketIO ، حيث لا توجد بيانات جلسة تحتاج إلى الاستمرار عبر المكالمات (فقط مكالمة واحدة ، المصافحة ، تحدث ، وهذا يعمل).

يتمثل الإصلاح في جزء AWS في السماح باستخدام الجلسات اللاصقة بطريقة ما لموازنة حمل الطبقة 4.

يتمثل الإصلاح في جزء SocketIO في جعله بحيث لا تتطلب مصافحة websocket سياق معرف الجلسة السابق (لا أعرف الغرض أو دورة الحياة حول هذا ؛ أفترض أنه موجود للمساعدة في الاقتراع الطويل ، وأكثر من ذلك) إعادة الاتصال بسرعة في حالة إنهاء الاتصال ؛ إذا قرر العميل أن الاتصال قد توقف ، فيمكنه إنشاء جلسة جديدة وإعادة الاتصال بنجاح ، بدلاً من أن ترفض الواجهة الخلفية تأكيد الاتصال لأنه يعتقد أن الاتصال موجود بالفعل).

قد يكون الإصلاح المحتمل هو استخدام Redis لاستمرار حالة الجلسة عبر جميع المثيلات. أنا لم أختبر هذا.

الحل البديل ، إذا كان التحميل الخاص بك يسمح بذلك ، هو التأكد أيضًا من مثيل عقدة واحدة فقط لكل منطقة توفر ، وتعطيل موازنة التحميل عبر المناطق. بهذه الطريقة ، ستتحول جميع المكالمات افتراضيًا إلى عقدة واحدة ، مع تجنب هذه المشكلة.

aidanbon لم أجد Proxy server to be "none" in the Software Configuration section ؟

أنا ببساطة أستخدم خادم ubuntu و MeteorJS مع نشر mup .. هل يمكنك الحصول على رابط لي من فضلك؟

هتافات

sahanDissanayake لقد وجدت خيار تهيئة خادم الوكيل عبر:

  1. انقر فوق "تكوين" في البيئة التي تهمك
  2. انقر فوق "تكوين البرنامج" من داخل صفحة التكوين
  3. القائمة المنسدلة "الخادم الوكيل" كما هو موضح في لقطة الشاشة السابقة.

ملاحظة: تم توفير بيئتي منذ عام تقريبًا. لست متأكدًا من تحديث لوحة AWS للبيئات الأحدث. ومع ذلك ، لا يزال بإمكاني رؤية هذه القائمة المنسدلة اليوم في بيئتي.

aidanbon أنا لا أستخدم أي خدمات أخرى غير EC2 .. لذا فإن إعداداتك ليست مناسبة لي؟ أو هل أحتاج إلى بدء استخدام خادم الوكيل هذا؟

لذا فإن المشكلة التي أواجهها هي أن مآخذ الويب لتطبيق الويب الخاص بي تعمل في المنفذ 8080 ، ولكن ليس في المنفذ 80.

هذه هي القضية

lostcolony شكرا لك على الملخص. لقد توصلت إلى نفس النتيجة. هل قرأت منشور المدونة هذا: https://medium.com/@Philmod/load -balancing-websockets-on-ec2-1da94584a5e9 # .hd2ectz8t؟ إنه يقول بشكل أساسي إنه يمكن للمرء أن يمرر الطبقة 4 (TCP) إلى مثيل HAProxy ، والذي يقوم بعد ذلك بإزالة رأس PROXY وتوجيه حركة المرور إلى المثيل الصحيح باستخدام جلسات ثابتة. ومع ذلك ، ليس من الواضح بالنسبة لي كيف يحصل جهازي HAProxy على تكوين قائمة خوادم "الواجهة الخلفية" الخاصة بهم وأين يتم تشغيلها وأين يتم تشغيل خادم socket.io الفعلي. هل يمكنك فهم ذلك؟

تحرير: أعتقد أنني نقرت الآن. إنه يعرف القائمة لأنه يمتلك مجموعة معروفة من الخوادم ولا يهتم بالتوسع التلقائي ...

سيتم تكوين قائمة الخادم في كل مربع HAproxy. لست متأكدا كيف
لجعل ذلك يعمل مع مثيلات ec2 التحجيم التلقائي ، ما لم تكتب بعضًا
بنية تحتية إضافية لتحديث تلك القائمة عندما يأتي خادم جديد
عبر الانترنت. يتم تشغيل Socket.io على نفس الخادم مثل تطبيق الويب الخاص بهم ، لذا
تأتي الاتصالات عبر Elb ، ويتم توحيدها إلى مثيل HAproxy ،
يضمن مثيل (مثيلات) HAproxy أن اتصالات IP دائمًا ما تنتقل إلى نفس الشيء
خادم الويب / التطبيق ، حيث تم إعداد socket.io.
في 13 كانون الثاني (يناير) 2016 ، الساعة 2:50 صباحًا ، كتب "فيليكس شليتر" [email protected] :

lostcolony https://github.com/lostcolony شكرا لك على الملخص. أنا
قد توصلوا إلى نفس النتيجة. هل قرأت منشور المدونة هذا:
https://medium.com/@Philmod/load -balancing-websockets-on-ec2-1da94584a5e9 # .hd2ectz8t؟
إنه يقول بشكل أساسي إنه يمكن للمرء أن يمرر الطبقة 4 (TCP) إلى ملف
مثيل HAProxy ، الذي يأخذ بعد ذلك رأس PROXY ويوجه ملف
حركة المرور إلى المثيل الصحيح باستخدام الجلسات الثابتة. ومع ذلك ، فهي ليست كذلك
من الواضح لي كيف يحصل جهازي HAProxy على قائمة الخوادم "الخلفية"
تم تكوينه وأين يتم تشغيله وأين يتم تشغيل خادم socket.io الفعلي.
هل يمكنك فهم ذلك؟

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/socketio/socket.io/issues/1846#issuecomment -171208211
.

lostcolony حسنًا ، لقد رأيت أن هناك مشروعًا مثيرًا للاهتمام فيما يتعلق https://github.com/markcaudill/haproxy-autoscale. ما لا أحصل عليه هو لماذا استخدم ELB أمام HAProxy؟ يجب أن يكون هناك مثيل HAProxy واحد فقط ، وإلا كيف تضمن أن ELB يرسل حركة المرور إلى مثيل HAProxy الصحيح؟ ما لم تكن (مثيلات HAProxy) تشترك في جدول لاصق مشترك بطريقة ما باستخدام ElastiCache أو Redis أو أي شيء من هذا القبيل؟ ... أنا أدرك أننا نخرج بعيدًا عن الموضوع.

إذا كان لديك HAProxies مهيأ لتوجيه الاتصالات بناءً على IP الخاص بك
يمكن أن يضمن أنه سينتهي به الأمر في نفس الحالة. هذا هو ، إذا كان HAProxies
جميعهم لديهم نفس القاعدة التي تنص على أن ip ABCD موجه إلى المثال الأول ،
ثم بغض النظر عن HAProxy الذي ضرب ELB ، سينتهي به الأمر في نفس الوقت
مكان. هذا ما يحدث في هذا الرابط الذي أرسلته ، إنهم يوازنون
عبر المصدر ، مما يعني أن مثيل HAProxy يقوم بتجزئة عنوان IP ويستخدم ذلك في
تحديد الحالة التي يذهب إليها. العديد من HAProxies ، بشرط أن يكونوا جميعًا
تعرف على نفس الحالات ، مما يؤدي إلى إرسال حركة المرور من موقع إلى
نفس المثيل الخلفي.

يوم الأربعاء ، 13 كانون الثاني (يناير) 2016 ، الساعة 1:19 مساءً ، فيليكس شليتر ، إخطارات github.com
كتب:

lostcolony https://github.com/lostcolony حسنًا ، رأيت أنه كان هناك ملف
مشروع مثير للاهتمام فيما يتعلق بالتوسع التلقائي على أمازون ، باستخدام HAProxy -
مفيد على الأقل كمرجع:
https://github.com/markcaudill/haproxy-autoscale. ما لا أحصل عليه هو السبب
استخدام ELB أمام HAProxy؟ يجب أن يكون هناك مثيل HAProxy واحد فقط ،
وإلا ، كيف تضمن أن يرسل ELB حركة المرور إلى اليمين
مثيل HAProxy؟ ما لم تكن (مثيلات HAProxy) تشترك في شيء مشترك
الجدول اللاصق بطريقة ما باستخدام ElastiCache أو Redis أو شيء من هذا القبيل
خطوط؟ ... أنا أدرك أننا نخرج بعيدًا عن الموضوع.

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/socketio/socket.io/issues/1846#issuecomment -171386260
.

lostcolony أنا أفهم أن التجزئة مشتقة بشكل

قاعدة تعيين التجزئة لمثيل هي نفسها في جميع HAProxy
حالات. وهذا يعني أن ABCD سينتج عنه نفس التجزئة بغض النظر عن ملف
مثيل HAProxy الذي يصل إليه ، وسيتم تعيين هذا التجزئة إلى نفس الخادم ، لا
بغض النظر عن مثيل HAProxy قيد الاستخدام ، بشرط أن يعرف كل HAProxy عنه
نفس الحالات (وربما بنفس الترتيب / نفس الأسماء). ال
لا يلزم معرفة عناوين IP الفعلية مقدمًا ، لأنها غير مادية.
سيتم تجزئة أي IP إلى نفس الخادم بغض النظر عن HAProxy الذي يمرره
عبر.

للحصول على مثال مزيف تمامًا (يستخدم HAProxy شيئًا ليس كذلك
يمكن التنبؤ بها ، أنا متأكد) ، تخيل أن لدينا ثلاثة خوادم ، تم تكوينها
بالترتيب مثل server0 و server1 و serve2 (التفاصيل الفعلية لا تهم ،
مجرد وجود ترتيب واضح ، ضمنيًا أمر جيد). كل HAProxy
المثيل لديه نفس الخوادم ، بنفس الترتيب. هم أيضا لديهم نفس الشيء
القاعدة فيما يتعلق بكيفية التعامل مع عنوان IP الوارد. لهذا المثال المبتذل ،
إنها تجمع الأجزاء الأربعة من العنوان كأعداد صحيحة (يمكن توسيعها بسهولة إلى
support IPv6 ، أضف الكل كـ hex في الأساس 10) ، وقسم على 3 ، خذ
بقية. إذن IP 123.12.61.24 = (123 + 12 + 61 + 24)٪ 3 ، أو 1. لذلك يتم توجيهه
إلى الخادم 1. لذلك بغض النظر عن مثيل HAProxy الذي يأتي فيه ، هذا
سيتم إرسال الاتصال إلى server1.

الآن ، إذا أصبح الخادم 1 غير متصل ، تتغير الخوارزمية عبر HAProxy
مثيلات ، لجمع جميع الأجزاء ، المعامل 2.

وهذا يعمل بشكل عام - ما لم تحصل على netsplit (أو تكوين ملف
تحتوي مثيلات HAProxy على قائمة خادم مختلفة). حيث يرى أحد HAProxy
3 حالات ، وآخر يرى 2. إذا حدث ذلك ، فلا يمكن ضمان ذلك
للوصول إلى نفس الخلفية. وبالفعل ، يمكن أن يكون ذلك مشكلة. ولكن
هذا هو الحل الموصوف في الرابط.

الأربعاء، 13 يناير 2016 في 15:51، فيليكس Schlitter [email protected]
كتب:

lostcolony https://github.com/lostcolony أفهم أن التجزئة هي
مشتق بشكل حتمي لملكية الفكرية ، ومع ذلك ، يجب أن يكون هناك تعيين
من "التجزئة -> مثيل". في حالتك أنت تقول أن هناك قاعدة
قائلا "ABCD موجه إلى المثال الأول" ، لكنك لا تريد
HAProxy لتحديد مكان إعادة التوجيه إلى نفسه ، في ضوء قائمة
الخوادم؟ بعد كل شيء ، "ABCD" هو مجرد عنوان IP لبعض العملاء وغير معروف
أمام.

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/socketio/socket.io/issues/1846#issuecomment -171428465
.

لقد وجدت أنه في Elastic Beanstalk على الرغم من أنني قمت بإعداد موازن التحميل لاستخدام 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

لن يعمل هذا إلا بنسبة 100٪ عندما يكون لديك مثيل واحد فقط ، لأن دعم الجلسة اللاصقة لا يعمل عبر TCP.

lostcolony ، ذكرنيwilliamcoates الآن أن أشكرك على التوضيح. لا أصدق أنني نسيت أن أفعل ذلك. كان شرحك مفيدًا للغاية ، لذا شكرًا لك على الوقت الذي استغرقته.

لذلك واجهت نفس المشكلة وتبين أنني قمت بإعداد البنك المركزي الأوروبي لاستخدام HTTPS.
لقد غيرت HTTPS إلى SSL ولم أعد أحصل على الرسالة بعد الآن.
لذلك ، فقط لا تستخدم HTTP / HTTPS ولكن TCP / SSL

اعتبارًا من أغسطس 2016 ، يمكنك استخدام Application Load Balancer (ALB) من Amazon بدلاً من ELB "الكلاسيكي". عملت "خارج الصندوق" بالنسبة لي مع المستمعين على HTTP 80 و HTTPS 443.

@ trans1t الرجل الحلو ، شكرا على المعلومات! وسوف تضطر إلى التحقق من ذلك.

niczak - لقد قمت أيضًا بالتبديل إلى ALB للالتصاق بحركة مرور المقبس. ومع ذلك ، فقد كافحت أولاً مع تكوين جلسات ALB الثابتة (حيث لم يكن هناك الكثير من المستندات حول هذا الموضوع ؛ على الأقل قبل بضعة أشهر). أخيرا برزت. الشيء الرئيسي هو أن "الثبات يتم تحديده على مستوى المجموعة المستهدفة" ، لذا تأكد من إنشاء مجموعة مستهدفة لخدمة حركة المرور الخاصة بك ثم إضافة الثبات إليها.

aidanbon هذه معلومات رائعة ، شكرًا جزيلاً لك على المشاركة!

بالنسبة لأي شخص لا يزال يواجه مشكلة مع AWS Application Load Balancer ، حاول تحديث سياسة الأمان الخاصة بك ، فقد واجهت نفس المشكلة على الرغم من أنها كانت تعمل بشكل جيد في الإعداد الدقيق لموقع ويب آخر ولكن لاحظت أن سياسة الأمان كانت متأخرة حوالي عام واحد. يبدو أن تحديثه إلى إصدار أحدث قد أدى إلى حل المشكلة.

michaelmitchell هل قمت بتغيير أي شيء أو قمت بتحديثه فقط بدون تعديل؟

لم أغير أي شيء في تطبيقي ، وكانت الخطوة الإضافية الوحيدة التي اتخذتها هي إزالة مستمع HTTPS على ALB وإعادة إضافته لأنه بعد التغيير إلى السياسة الجديدة لم يبدو أنه يعمل.

ومع ذلك ، علمت أن رؤية الخطأ حتى بعد تحديث سياسة الأمان من المحتمل أن تكون جلسة المتصفح الخاصة بي تتمسك بسياسة الأمان القديمة ، لذلك لست متأكدًا مما إذا كانت إضافة / إعادة إضافة المستمع ضرورية حقًا ، ولكن فتح وضع التصفح المتخفي كان يعمل بشكل جيد وبعد كان إغلاق جميع جلسات Chrome الخاصة بي وإعادة فتحه يعمل بشكل جيد ولم أره منذ ذلك الحين.

من الجيد أن تعرف ، شكرا!

لو فين. 31 مارس 2017 ، 12:02 ، Michael Mitchell [email protected] أ
écrit:

لم أغير أي شيء في طلبي ، وكانت الخطوة الإضافية الوحيدة التي قمت بها
أخذ هو إزالة وإعادة إضافة مستمع HTTPS على ALB كما يلي
التغيير إلى السياسة الجديدة لا يبدو أنه يعمل.

لكنني علمت أن رؤية الخطأ حتى بعد تحديث الأمان
السياسة كانت على الأرجح جلسة المتصفح الخاصة بي مع التمسك بسياسة الأمان القديمة
لذلك لست متأكدًا مما إذا كانت إضافة / إعادة إضافة المستمع ضرورية حقًا ، ولكن
فتح وضع التصفح المتخفي يعمل بشكل جيد وبعد إغلاق جميع جلسات Chrome الخاصة بي
وإعادة فتحه يعمل بشكل جيد ولم أره منذ ذلك الحين.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/socketio/socket.io/issues/1846#issuecomment-290672158 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/ADrIi_SXqccWOLUMIWF1IhClGXvKAGMcks5rrM8sgaJpZM4C0swP
.

يبدو أن هذا الخيط أصبح مكانًا لاكتشاف المشكلات مع AWS / socket.io -

الإعداد الخاص بي هو أن يقوم العميل بإجراء طلب HTTPS مع بيانات اتصال socket.io.
يجب أن يستجيب طلب HTTPS مع ملفات تعريف الارتباط اللازمة للجلسات الثابتة. المشكلة هي أنني غير قادر على تمرير رأس cookie في اتصال socket.io.

أنا أستخدم 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 _must_ هو المثيل الذي يصل إليه اتصال المقبس.

بمجرد إنشاء مأخذ توصيل (إذا وصل إلى المثيل الصحيح بسبب الحظ الغبي) فإنه يظل موجودًا وتعمل الأشياء بشكل جيد ، تكمن المشكلة في جعل مقبس الويب يصل إلى نفس نقطة النهاية مثل طلب HTTPS.

غريزتي الأولى هي الاستخدام

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

هذا يعمل في node ، لكن في المتصفح cookie هو عنوان محظور في طلبات XMLHTTP ، لذلك لا يمكنني إرسالها معه.

هل فعل أحد شيء مشابه؟

لم أفعل شيئًا مشابهًا ، ولكن ، بينما لا تزال ALBs لا تملك توجيهًا قائمًا على الرأس ، فإنها تمتلك توجيهًا قائمًا على المضيف. هذا أمر صعب للغاية ، على هذا النحو ، ولكن يمكنك أن تجعله في الأساس بحيث يكون لكل مثيل خلف ALB مسار واضح إليه ، يعرف عنه المثال. عندما يخرج طلب HTTP الأولي هذا ، يتضمن جزء من الاستجابة المسار ، ويشتمل الاتصال الخاص بمقبس الويب على هذا المسار. أي أن طلب HTTP يضرب المثيل "5" (بناءً على أي معايير ؛ ستكون UUIDs التي تم إنشاؤها أفضل) ، ويعيد "5" كجزء من الاستجابة ، ويتم فتح مقبس الويب إلى url / 5. يحتوي ALB على قاعدة يتم توجيه url / 5 إلى المثال 5.

إذا كنت تستخدم القياس التلقائي (وكانت مثيلاتك ماشية وليست حيوانات أليفة) ، فستحتاج إلى تشغيل الكود الخاص بك على المثيل لتعديل إعدادات ALB لتوجيه المجال المناسب إليه.

اقرأ المزيد هنا: https://aws.amazon.com/blogs/aws/new-host-based-routing-support-for-aws-application-load-balancers/

ومع ذلك ، سأقول أيضًا أنك ربما تريد فقط تجنب النمط الذي تستخدمه إذا كان ذلك ممكنًا على الإطلاق. يجب تخزين البيانات الواردة في طلب HTTP بطريقة يمكن الوصول إليها من كل مثيل (DB أو ما شابه ذلك) ، أو يجب إرسالها عبر اتصال websocket بمجرد إنشائه. كما هو الحال ، لا يزال من الممكن أن يكون لديك مثيل يموت بين طلب HTTP وفتح مقبس الويب ، ويمكن أن تواجه نفس المشكلة (وإن كان ذلك في كثير من الأحيان)

lostcolony شكرًا على النصيحة - فهذا بالتأكيد يستحق المحاولة.

طلب http هو ما يؤدي إلى تشغيل خادم websocket (إنه في الواقع في حاوية عامل إرساء ، ولكن يتم تجريده بعيدًا). يجب توجيه الطلبين إلى نفس المثيل حتى يتواجد خادم websocket على المثيل الذي يتم الاتصال به

مع هذا الخط ، فإنه يساعد على الجلوس خادم jupyter خلف elb.

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

في حالة وصول شخص ما إلى هذه التذكرة مع kubernetes على نظام AWS.

لقد قمت فقط بتعطيل HTTP2 ثم لا بأس بذلك بالنسبة لي. ليس عليك فعل أي شيء آخر بخصوص ELB.

Screen Shot 2019-12-13 at 16 12 49

مرحبا،
لدي نفس المشكلة ، على الرغم من أنني أستخدم SockJS.
تطبيقي هو تطبيق Java Spring 4 ، يعمل على آلة التطوير و
الحصول على نفس الخطأ على AWS.
يبدو أنه تم إسقاط رأس الترقية بواسطة شخص ما ، يمكنني رؤيته على العميل.

يمكن أن تجد حلا بعد ...

مرحبًا @ yoav200 ،

انقذني.
أنا عالق في نفس المشكلة. الرجاء المساعدة
أنا أستخدم Springboot 2.x و SockJs لمقبس الويب
لقد قمت بإنشاء تطبيق tomcat المنتشر في نظام AWS ،
ساق الفاصولياء المرن مع موازن الحمل الكلاسيكي

الآن المشكلة
مطور iOS غير قادر على الاتصال ، لقد وصل إلى الواجهة الخلفية الخاصة بي لكنه فشل أثناء المصافحة
فيما يلي السجلات التي أحصل عليها في كل من CLB و ALB


2019-12-13 15: 21: 22.662 DEBUG 27543 --- [nio-8080-exec-2] oswsDispatcherServlet: GET "/ wtchat / websocket" ، المعلمات = {}
2019-12-13 15: 21: 22.701 DEBUG 27543 --- [nio-8080-exec-2] oswsssWebSocketHandlerMapping: تعيينه إلى org.springframework.web.socket.sockjs.support. SockjshttpreceShandler @ 30C6A17.
2019-12-13 15: 21: 22.714 DEBUG 27543 --- [nio-8080-exec-2] oswssthDefaultSockJsService: معالجة طلب النقل: احصل على 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 التقييمات