Nano Hash - криптовалюты, майнинг, программирование

Балансировщик нагрузки приложений AWS и socket.io

У меня есть чат-комната socket.io, трафик которой увеличивается, поскольку мы работаем на одной машине. Мы провели тесты с использованием библиотеки ws для сокетов, и они работают намного лучше, что позволяет лучше использовать наше оборудование. Однако за это пришлось бы переписывать наше приложение.

Наше приложение socket.io позволяет пользователям создавать частные чаты, которые реализуются с использованием пространств имен. Например

localhost:8080/room/1
localhost:8080/room/2
localhost:8080/room/3

Когда все находится в одном экземпляре, это довольно просто, но сейчас мы стремимся расширить эту емкость на несколько узлов.

Мы запускаем этот экземпляр в облаке Amazon. Раньше казалось, что масштабирование веб-сокетов было проблемой с ELB. Мы заметили, что Amazon теперь поддерживает балансировщик нагрузки приложений, который поддерживает веб-сокеты. Звучит здорово, но после прочтения документации я должен признать, что на самом деле не знаю, что это значит. Если я использую socket.io с тысячами пространств имен, нужно ли просто размещать экземпляры за этим ALB, и все будет работать? Мои основные вопросы:

Если x пользователей присоединятся к пространству имен, будет ли ALB автоматически перенаправлять мои сообщения нужным пользователям и от них? Допустим, у меня есть 5 экземпляров vanilla socket.io, работающих за ALB. Пользователь 1 создает пространство имен. Проходит несколько часов, и пользователь 99999 приходит и хочет присоединиться к этому пространству имен, нужно ли будет писать какой-либо дополнительный код для этого или alb перенаправит все туда, куда следует? То же самое касается отправки и получения сообщений?


  • Просто чтобы быть уверенным, чего вы хотите добиться: одна комната для каждого экземпляра или комната может обрабатываться несколькими экземплярами? 03.05.2017
  • @MarcosCasagrande Room может обрабатываться несколькими экземплярами 03.05.2017

Ответы:


1

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

В своей документации socket.io предоставляет способ сделай это:

Теперь, когда у вас есть несколько узлов Socket.IO, принимающих соединения, если вы хотите транслировать события всем (или даже всем в определенной комнате), вам понадобится какой-то способ передачи сообщений между процессами или компьютерами.

Интерфейс, отвечающий за маршрутизацию сообщений, называется адаптером. Вы можете реализовать свой собственный поверх socket.io-adapter (путем наследования от него) или использовать тот, который мы предоставляем поверх Redis: socket.io-redis:

var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));

Настройка ALB

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

введите описание изображения здесь введите здесь описание изображения


Альтернатива с использованием маршрутизации ALB без адаптера socket.io.

Если бы я хотел избежать базы данных Redis. Например, если мои комнаты созданы пользователями, если пользователь А создает комнату на экземпляре 4, если другой пользователь хочет присоединиться к этой комнате, как они узнают, на каком экземпляре он находится? Нужен ли мне адаптер здесь тоже?

Целью этого варианта является назначение каждой комнаты конкретному экземпляру EC2. Мы собираемся добиться этого с помощью маршрутизации ALB< /а>

N комнат > 1 экземпляр

Шаг 1:

Вам нужно будет изменить URL-адрес вашей комнаты на что-то вроде:

/i1/room/550
/i1/room/20
/i2/room/5
/i5/room/492

существование:

/{instance-number}/room/{room-id}

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

Шаг 2:

Создайте N целевых групп (N — количество экземпляров, которые у вас есть на данный момент)

Изображение

Шаг 3:

Зарегистрируйте каждый экземпляр в каждой целевой группе

Целевые группы > Целевая группа экземпляра X > вкладка «Цель» > «Редактировать» > «Выбрать экземпляр X» > добавить в зарегистрированные

Target group X > EC2 Instance X
Target group Y > EC2 Instance Y

введите описание изображения здесь

Шаг 4:

Изменить целевые правила ALB

Балансировщики нагрузки > Ваш ALB > Прослушиватели > Просмотр/редактирование правил

введите описание изображения здесь

Шаг 5:

Создайте одно правило для каждой целевой группы/экземпляра со следующими настройками:

  • ЕСЛИ > Путь: /iX/room/*
  • ТОГДА > переслать: instanceX

введите описание изображения здесь


введите описание изображения здесь

Если у вас есть эта настройка, когда вы вводите:

  • /i1/room/550 вы будете использовать инстанс 1 EC2.
  • /i2/room/200 будет использовать инстанс 2 EC2

и так далее.

Теперь вам нужно будет создать свою собственную логику, чтобы сбалансировать комнаты в ваших инстансах. Вы не хотите, чтобы в одном экземпляре размещались почти все группы.

Я рекомендую первый подход, поскольку его можно легко масштабировать автоматически.

03.05.2017
  • Спасибо за отличное объяснение! Итак, чтобы подтвердить этот подход, мне нужно будет запустить базу данных Redis? Это ответ на мой вопрос, но у меня есть побочный вопрос. Если бы я хотел избежать базы данных Redis, сработал бы первый предложенный вами подход? Например, если мои комнаты создаются пользователями, если пользователь А создает комнату на экземпляре 4, если другой пользователь хочет присоединиться к этой комнате, как они узнают, на каком экземпляре он находится? Нужен ли мне адаптер здесь тоже? 03.05.2017
  • Я бы добавил пояснение, как назначить комнату конкретному экземпляру. Но, пожалуйста, дайте мне несколько часов, так как я сейчас не за компьютером. И вам не понадобится адаптер, ALB позаботится о маршрутизации в нужную комнату экземпляра. 03.05.2017
  • В комнатах будет установлен лимит пользователей, обусловленный некоторой логикой на сервере, так что это меня не волнует. Пожалуйста, не торопитесь, звучит здорово, спасибо! 03.05.2017
  • @user2924127 user2924127 Вы проверили мой обновленный ответ, где я решаю I wanted to avoid having a redis database, would the first approach you suggested work 07.05.2017
  • Спасибо за ответ @MarcosCasagrande. Я использую первый подход адаптера socket.io, в этом случае мне нужна помощь в отношении того, сколько соединений будет обрабатывать socket.io на одном экземпляре m4 aws и как реализовать socket.io redis в код и тест одинаковые? В настоящее время я использую веб-сокет Node.js и ASP.NETC # на экземпляре M4.Large и сталкиваюсь с такими проблемами, как некоторые сообщения, не доходящие до клиентского приложения из-за высокого трафика на сервере (загрузка ЦП от 90 до 95%). Пожалуйста, направьте меня .. Спасибо! 29.08.2018
  • Количество подключений — это то, что вам придется проверить самостоятельно, провести несколько тестов и посмотреть, сколько подключений обрабатывает ваше приложение. Я не могу дать вам ответ, потому что это будет зависеть от вашего кода, настроек вашей ОС... Что касается реализации сокета Redis, вы должны прочитать документацию, но все, что вам нужно, это сервер Redis. AWS предоставляет сервис elasticache с кластерами Redis. 29.08.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..