Подтвердить что ты не робот

Проксирование WebSockets с балансиром нагрузки TCP без липких сеансов

Я хочу проксировать соединения WebSocket с несколькими серверами node.js, используя Amazon Elastic Load Balancer. Поскольку Amazon ELB не обеспечивает фактическую поддержку WebSocket, мне нужно будет использовать его обмен сообщениями с TCP-сетью. Тем не менее, я пытаюсь понять, как это будет работать без какой-либо липкой функциональности сеанса.

Я понимаю, что WebSockets работают, сначала отправив HTTP-запрос на обновление с клиента, который обрабатывается сервером, отправив ответ, который правильно обрабатывает аутентификацию ключа. После того как сервер отправит этот ответ и одобрен клиентом, существует двунаправленное соединение между этим клиентом и сервером.

Однако скажем, клиент после утверждения ответа сервера отправляет данные на сервер. Если он отправляет данные в балансировщик нагрузки, а балансировщик нагрузки затем передает эти данные на другой сервер, который не обрабатывает первоначальный запрос обновления WebSocket, то как этот новый сервер будет знать о соединении с WebSocket? Или клиент автоматически обойдется балансировщиком нагрузки и отправит данные непосредственно на сервер, который обрабатывал первоначальное обновление?

4b9b3361

Ответ 1

Я думаю, что нам нужно понять, чтобы ответить на этот вопрос, как именно базовое TCP-соединение развивается в течение всего процесса создания WebSocket. Вы поймете, что липкой частью соединения WebSocket является основное TCP-соединение. Я не уверен, что вы подразумеваете под "сессией" в контексте WebSockets.

На высоком уровне инициирование "соединения WebSocket" требует, чтобы клиент отправил HTTP-запрос GET на HTTP-сервер, тогда как запрос включал поле заголовка Upgrade. Теперь для этого запроса клиент должен установить TCP-соединение с HTTP-сервером (это может быть очевидно, но я думаю, здесь здесь важно указать это явно). Затем последующий ответ HTTP-сервера отправляется через TCP-соединение ..

Обратите внимание, что теперь, после отправки ответа сервера, TCP-соединение остается открытым/живым, если он не активно закрыт ни клиентом, ни сервером.

Теперь, согласно RFC 6455, стандарт WebSocket, в конце раздел 4.1:

Если ответ сервера проверяется, как указано выше, это сказал, что соединение WebSocket установлено и что Соединение WebSocket находится в состоянии OPEN

Я читаю отсюда, что то же TCP-соединение, которое было инициировано клиентом перед отправкой первоначального запроса HTTP GET (Upgrade), просто останется открытым и теперь будет служить транспортным уровнем для полнодуплексного соединения WebSocket, И это имеет смысл!

В отношении вашего вопроса это означает, что балансировщик нагрузки будет играть только роль до того, как будет выполнен первоначальный запрос HTTP GET (Upgrade), то есть до того, как будет установлено одно и только соединение TCP, связанное с указанным соединением соединения WebSocket между двумя конечные точки связи. После этого TCP-соединение остается установленным и не может "перенаправляться" сетевым устройством между ними.

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

Если вы ссылались на что-то еще с "session", то, вероятно, это сеанс, который вводится уровнем приложения, и мы не можем комментировать его.

Изменить в отношении ваших комментариев:

поэтому вы говорите, что балансировщик нагрузки не участвует в TCP подключение

Нет, это не так, по крайней мере, вообще. Это определенно может повлиять на установление соединения TCP, в том смысле, что оно может решить, что делать с попыткой подключения к клиенту. Специфика зависит от точного типа балансировки нагрузки (*, см. Ниже). Важно: после установления соединения между двумя конечными точками - в то время как я не считаю, что балансировщик нагрузки является конечной точкой, я обращаюсь к клиенту WebSocket и серверу WebSocket - обе конечные точки больше не будут меняться в течение срока службы соединения WebSocket, Балансировщик нагрузки может * по-прежнему находиться в сетевом пути, но можно предположить, что он больше не принимает никакого влияния.

Поэтому полнодуплексное соединение находится между клиентом и конечный сервер?

Да!

*** Существуют различные типы балансировки нагрузки. В зависимости от типа роль балансировки нагрузки отличается после установления соединения между двумя конечными точками. Примеры:

  • Если балансировка нагрузки происходит на основе DNS, то балансировщик нагрузки вообще не участвует в конечном соединении TCP. Он просто сообщает клиенту, кому хост должен подключиться напрямую.
  • Если балансировка нагрузки работает как ELB уровня 4 от AWS (docs здесь), то это так сказать прокси-сервер TCP-соединения. Таким образом, клиент фактически увидит сам ELB как сервер. Однако происходит то, что ELB просто перенаправляет пакеты в обоих направлениях без изменений. Следовательно, он все еще активно участвует в TCP-подключении, просто прозрачно. В этом случае на самом деле существуют два постоянных соединения TCP: один от вас до ELB и один от ELB до сервера. Они снова являются постоянными для жизни вашего соединения с WebSocket.

Ответ 2

WebSocket использует постоянное TCP-соединение и, следовательно, требует, чтобы все IP-пакеты для этого TCP-соединения были переадресованы на один и тот же бэкэнд-сервер (для срока службы TCP-соединения).

Он должен быть липким. Это отличается от L7 HTTP LB, которые могут отправлять по HTTP-запросу.

LB может работать липким с помощью разных подходов, т.е.

  • хэш исходного IP/порта для набора активных серверных серверов
  • при установлении соединения TCP выберите сервер базы данных и помните, что