Поддерживает ли балансировщик нагрузки приложений WebSockets?

У меня есть приложение Elastic Beanstalk, которое изначально было настроено для использования Classic Load Balancer. Я обнаружил, что это вызывает ошибки при подключении через WebSocket. Из-за этого я настроил приложение для использования вместо этого Application Load Balancer, потому что мне сказали, что ALB поддерживают WebSockets. Однако похоже, что это не так: я получаю точно такую ​​же ошибку при попытке подключиться к моему ALB через WebSocket.

Действительно ли ALB поддерживают WebSocket? Документация AWS по этому поводу противоречива. На этой странице говорится, что она поддерживает только HTTP. и HTTPS. Нет никаких руководств по настройке ALB для поддержки WebSocket.


person jameshfisher    schedule 05.09.2016    source источник
comment
Из официального блога: aws.amazon.com/blogs/ aws / new-aws-application-load-balancer ALB обеспечивает встроенную поддержку WebSocket через протоколы ws: // и wss: //.   -  person Mark B    schedule 05.09.2016
comment
несмотря на это объявление и раздел часто задаваемых вопросов для ALB, я также получаю ту же ошибку в ALB (статус http 501 не реализован)   -  person nont    schedule 15.09.2016
comment
несмотря на aws.amazon.com/elasticloadbalancing/applicationloadbalancer/   -  person nont    schedule 15.09.2016
comment
Socket.io имеет проблемы и, похоже, не работает из коробки.   -  person coolboyjules    schedule 10.11.2018


Ответы (5)


Мне удалось заставить WebSockets работать с новым балансировщиком нагрузки приложений (ALB).

Сначала создайте новую целевую группу для вашего ALB. Эта целевая группа должна использовать тот же порт, что и ваше приложение, и ей необходимо будет настроить проверки работоспособности. Однако главное отличие состоит в том, что вы должны включить липкость.

«Добавить

Затем добавьте новое правило слушателя в свой ALB. Это правило должно иметь путь для маршрутизации настройки WebSocket - /socket.io. Кроме того, в качестве имени целевой группы укажите только что созданную целевую группу.

Добавить правило прослушивания для WebSocket

Я использую Node / Hapi / Socket.io для своего сервера (работающего на экземпляре, полученном из Amazon Linux AMI). Базовая настройка:

const hapi = require('hapi');
const websocket = require('./WebSocket');

var server = new hapi.Server();
server.connection(config.Application);
websocket.Initialize(server.listener);

где WebSocket.js - это

var io = null;

module.exports = {

    Initialize: function (http) {

        io = require('socket.io')(http);

        io.on('connection', function (socket) {
            console.log('Websocket ' + socket.id + ' connected.');

            socket.on('disconnect', function () {
                console.log('Websocket ' + socket.id + ' disconnected.');
            });
        });
    }
};

Я использую Angular 1.5x для своего клиента с socket.io-client. Важно настроить параметры клиента WebSocket следующим образом, иначе вы не сможете подключиться.

(function () {

    'use strict';

    angular
        .module('XXXXX', [])
        .run(runHandler);

    runHandler.$inject = ['WebSocketService'];

    function runHandler(WebSocketService) {
       WebSocketService.Initialize();
    }
})();

Сервис WebSocket:

(function () {

    'use strict';

    angular
        .module('XXXXX')
        .factory('WebSocketService', WebSocketService);

    WebSocketService.$inject = [];

    function WebSocketService() {

        var socket = null;

        function initialize() {

            var url = 'http://' + ALB_URL + ':5800';

            socket = io(url, {transports: ['websocket'], upgrade: false});

            socket.on('connect', function () {
                console.log('Socket connected');
            });

            socket.on('disconnect', function () {
                console.log('Socket disconnected');
            });
        }

        return {
            Initialize: initialize
        };
    }
})();
person programmerj    schedule 04.11.2016
comment
Какая у вас конфигурация проверки работоспособности? Есть ли у socket.io или кода вашего приложения специальная конечная точка проверки работоспособности? В моем случае запрос / приводит к ответу HTTP 426, который ALB не считает нормальным. - person dskrvk; 24.11.2016
comment
У меня за ALB две ВМ. На каждом из них размещается веб-сервис Node. У меня есть конечная точка REST по адресу http: ‹server›: 5800 / v1 / monitor / ping, которая возвращает текущую дату / время сервера в виде строки с HTTP 200 OK. Я настраиваю эту информацию в своем API (не веб-сокет) Target Group- ›Health Checks. - person programmerj; 28.11.2016
comment
@programmerj Итак, какой у вас ALB_URL? xxx.us-east-1.elasticbeanstalk.com/socket.io:5800? Требуется ли, чтобы путь был в точности socket.io или он произвольный? Flask-socketio предоставляет веб-сокет через порт 5000, так что я буду использовать порт 5000? - person Alpenglow; 11.04.2017
comment
Привет @Alpenglow. Исходя из памяти, потому что я больше не использую этот стек, но ALB_URL будет сгенерированным URL-адресом балансировщика нагрузки приложения или, в моем случае, URL-адресом, созданным в Route53, который указывает на балансировщик нагрузки приложения. Я не думаю, что путь должен быть «socket.io», если клиент соответствует. Я считаю, что в вашем случае вы бы использовали 5000. - person programmerj; 12.04.2017
comment
Я мог заставить это работать, только включив липкость баланса нагрузки, несмотря на то, что документация AWS указала на то, что в этом нет необходимости: docs.aws.amazon.com/elasticloadbalancing/latest/application/ - person n4cer500; 25.04.2017
comment
Спасибо за этот пост. Однако была ли у кого-нибудь проблема, когда сокет отключается, а затем повторяет попытку? Кажется, что он остается подключенным какое-то время, а затем периодически теряет соединение. И я заметил, что он выдает ошибку во время рукопожатия WebSocket: Неожиданный код ответа: 502 - есть идеи? - person Aaron; 26.12.2017
comment
Извините, я ничего не делал с веб-сокетами и ALB с тех пор, как опубликовал этот ответ. Удостоверились ли вы, что вы включили привязку к целевой группе? - person programmerj; 27.12.2017
comment
Обратите внимание: если вы используете эластичный бобовый стебель, вы должны следовать этому ответу, в котором есть решение stackoverflow.com/questions/47584103/ - person coolboyjules; 01.02.2019

ALB поддерживает Websocket, но подсистема балансировки нагрузки может закрыть соединение, если экземпляр не отправляет некоторые данные по крайней мере каждые секунды «тайм-аут простоя».

person Namtrh    schedule 06.11.2016

Балансировщик нагрузки приложений поддерживает веб-сокет. Но нет поддержки проверки работоспособности веб-сокетов до 23 февраля 2017 года. Они могут добавить опцию позже. Если вы хотите использовать веб-сокет за Application Load Balancer, вам необходимо настроить проверку работоспособности HTTP или HTTPS для вашей целевой группы.

Из документа AWS: «Обратите внимание, что проверки работоспособности не поддерживают WebSockets».

Ссылка: http://docs.aws.amazon.com/elasticloadbalancing/latest/application/target-group-health-checks.html

person Bijohn Vincent    schedule 23.02.2017
comment
Напоминаем, что мы находимся в 2018 году, около 2019 года, а AWS все еще не поддерживает проверки работоспособности WSS: '(docs.aws.amazon.com/elasticloadbalancing/latest/application/ все еще сказал - person Cyril Duchon-Doris; 03.10.2018

ALB (балансировщик нагрузки приложений) поддерживает веб-сокеты. вы можете проверить здесь https://aws.amazon.com/blogs/aws/new-aws-application-load-balancer/ введите описание изображения здесь

также ALB закрывает соединение в зависимости от настроенного тайм-аута простоя.

SnapShot из указанного выше блога

person saurav omar    schedule 26.10.2018
comment
На самом деле это не помогает. - person coolboyjules; 01.02.2019

С точки зрения nodejs. Когда мы используем socket io на стороне клиента и вызываем библиотеку socket.js
вот так

const socket = io('domain.com');

я заметил, что когда я указал Http в качестве протокола, он перенаправил вызов на ws: //domain.com, но когда я указал https, он перенаправился на wss: //domain.com, и я получал эту ошибку: Ошибка во время WebSocket рукопожатие: Неожиданный код ответа: 400 то, что я сделал, я указал

const socket = io(window.location.origin, {reconnect: true,transports: ['websocket']});

что действительно решило мою проблему

person Ansh Nagrath    schedule 12.12.2019