Как обрабатывать соединения wesocket на серверах с балансировкой нагрузки

Наше веб-приложение .net core в настоящее время принимает соединения через веб-сокеты и отправляет данные клиентам при определенных событиях (редактирование, удаление, создание некоторых наших объектов).

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

Каков общепринятый способ решения этой проблемы? Лучший способ, который я могу придумать, — отправить это же событие всем узлам в кластере, чтобы они также могли обновлять своих клиентов. Это возможно? Откуда мне знать о других узлах в кластере?

Будет размещен в AWS.




Ответы (2)


Вам необходимо распространить событие на все узлы в кластере, чтобы каждый из них мог отправить обновление своим клиентам веб-сокетов. Обычный способ сделать это в AWS — использовать SNS для распространения события на все узлы. Вы также можете использовать для этого ElastiCache Redis Pub/Sub.

person Mark B    schedule 24.10.2017
comment
Я предполагаю, что мне нужно использовать комбинацию SNS и SQS здесь? SNS, отправляющий события через HTTPS, снова столкнется с балансировщиком нагрузки. Как мне направить его на конкретный узел, который не будет доступен из Интернета? - person Craigt; 28.10.2017
comment
Я больше думал о том, что каждый сервер будет подписываться на тему SNS, используя его прямое DNS-имя, чтобы уведомления SNS не попадали в балансировщик нагрузки, а направлялись непосредственно на сервер. ElastiCache Redis Pub/Sub, вероятно, является более чистой реализацией, поскольку все соединения исходят с серверов, и вам не придется управлять подписками SNS. - person Mark B; 28.10.2017
comment
В итоге я выбрал ElastiCache Redis Pub/Sub, как вы предложили. Для меня это было намного проще и чище. Спасибо за предложение. - person Craigt; 29.10.2017

В качестве альтернативы SNS или Redis вы можете использовать Kinesis Stream. Но прежде чем перейти по этой ссылке, прочитайте об Apache Kafka, потому что документация AWS не очень хорошо работает. объяснить, почему вы будете использовать Kinesis для чего-то другого, кроме загрузки журналов.

Подводя итог: Kinesis — это «постоянный журнал транзакций»: все, что вы записываете в него, хранится в течение некоторого времени (по умолчанию сутки, но вы можете оплатить до 7 дней) и доступно для чтения любому количеству потребителей.

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

Основная проблема, с которой я столкнулся в Kinesis, заключается в том, что здесь нет механизма «длинного опроса», как в SQS. Данный запрос на чтение может возвращать или не возвращать данные. Что он действительно говорит вам, так это то, находитесь ли вы в настоящее время в конце потока; если нет, вы должны продолжать читать, пока не станете. И, конечно же, Amazon задушит вас, если вы будете читать слишком быстро. В результате ваш код имеет тенденцию к сну.

person kdgregory    schedule 28.10.2017