Масштабирование с помощью липких сессий и веб-сокетов

Изначально у нас есть два экземпляра AWS EC2 с node.js, работающими за балансировщиком нагрузки с фиксированными сессиями. По мере увеличения нагрузки добавляется больше экземпляров.

Но мы сталкиваемся с проблемами при таком подходе. Так как наше приложение предназначено в основном для воркшопов, нагрузка обычно увеличивается в течение короткого промежутка времени (начало воркшопа) и у каждого участника воркшопа залипает сессия с первыми двумя инстансами, а у новых практически нет. Из-за этого производительность остается плохой.

Первая мысль была: давайте отключим липкие сессии. Но это разрушает наши веб-сокеты, потому что им нужны липкие сеансы (по крайней мере, это то, что я читал). Другая проблема связана с уменьшением нагрузки. Экземпляры закрываются, и сокет-соединения также теряются.

Есть ли способ переместить пользовательские сеансы между экземплярами или заставить веб-сокеты работать без липких сеансов (возможно, с Redis)?


person Tobias Stangl    schedule 22.01.2018    source источник
comment
Похоже, вам нужен брокер публикации/подписки   -  person Gabriel Bleu    schedule 22.01.2018
comment
На самом деле мы используем pubsub с Redis, но без липких сессий невозможно установить соединение через веб-сокет.   -  person Tobias Stangl    schedule 22.01.2018
comment
Ваш вопрос отмечен тегом ELB, знаете ли вы о ALB< /а>   -  person Gabriel Bleu    schedule 22.01.2018
comment
Нет, я не был. Маршрутизация на основе содержимого кажется решением моей проблемы. Спасибо!   -  person Tobias Stangl    schedule 23.01.2018


Ответы (1)


Решением стал балансировщик нагрузки приложений ( см. комментарий).

  1. Сначала нам пришлось отключить опрос, потому что с остальными это не работало. Это делается путем определения транспортов вручную.

    let ioSocket = io('', {
        path: '/socket.io-client'
        transports: ['websocket']
    
  2. После этого мы настроили стандартный балансировщик нагрузки приложений с двумя целевыми группами: одна для веб-сокетов и одна для всех остальных запросов. Правило для целевой группы websocket соответствует определенному пути через регулярное выражение:

Шаблон пути

  1. Последней проблемой было масштабирование: если один из инстансов отключится из-за меньшей нагрузки на кластер, соединения могут быть потеряны. Это было исправлено простым переподключением после отключения в клиенте (в нашем случае приложение angular):

    [...]
    this.socket.on('disconnect', () => {
        // Reconnect after connection loss
        this.connect();
    });
    [...]
    
person Tobias Stangl    schedule 24.01.2018