Назад | Перейти на главную страницу

Следует ли отключить proxy_buffering в NGINX для поддержки потоковой передачи SockJS XHR?

У меня есть «одностраничное» веб-приложение, которое требует двунаправленной связи между клиентом и сервером.

Первоначально приложение было разработано для работы с WebSockets, но было изменено для использования SockJS с отключенной поддержкой WebSocket.

Клиенты, использующие библиотеку SockJS, склонны использовать «XHR Streaming» как средство двунаправленной связи.

Сервер представляет собой веб-приложение Java, использующее реализацию Spring для сервера SockJS (из модуля Spring WebSocket), размещенного в Tomcat.

NGINX используется как обратный прокси для Tomcat.

Конфигурация NGINX по умолчанию предназначена для proxy_buffering быть включенным.

Документация NGINX неадекватно объясняет поведение буфера: не очевидно, при каких обстоятельствах буфер будет сброшен (то есть когда данные будут фактически отправлены клиенту), если данные передаются (из Tomcat) в течение длительного времени. HTTP-соединение.

Мое наблюдение заключается в том, что данные, отправленные с сервера (ответ на запрос клиента), могут находиться в буфере NGINX до тех пор, пока для этого клиента не произойдет следующий сгенерированный сервером сигнал SockJS. Результатом этого является задержка в 25 секунд передачи ответа клиенту!

Я могу очень надежно воспроизвести эту проблему путем экспериментов - поведение детерминировано, но я не могу объяснить взаимосвязь между настроенным размером (ами) буфера, размером передаваемых данных и поведением NGINX.

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

Основная цель - уменьшить задержку ответов на клиентские команды.

NGINX видит только долгоживущий HTTP-поток; разделение содержимого потока на отдельные ответы на команды (для немедленной отправки) потребует от NGINX понимания проприетарного протокола SockJS, чего он не может.

Поэтому я считаю, что политика буферизации NGINX принципиально несовместима с моим вариантом использования, и планирую отключить proxy_buffering; это мудро?

Документация NGINX предполагает, что если proxy_buffering отключен, вышестоящий сервер (Tomcat) будет вынужден держать HTTP-ответ открытым до тех пор, пока все данные не будут получены клиентом (что кажется разумным определением буферизации!).

Соответственно, документация NGINX не рекомендует отключать proxy_buffering, так как это потенциально приведет к потере ресурсов вышестоящего сервера.

Однако, поскольку мои клиенты используют потоковую передачу XHR, мой сервер уже обязан поддерживать HTTP-соединение открытым для каждого активного клиента (верно?). Следовательно, отключение proxy_buffering не должно отрицательно влиять на мой сервер Tomcat; это верно?

Я думаю, что вы правы в своих рассуждениях. У меня есть приложение с такой же настройкой, sockjs за прокси-сервером nginx. Мы наблюдали много разорванных соединений из местоположения с высокой задержкой. Найдя этот пост и выключив proxy_buffering наши проблемы с разорванными соединениями прояснились.

Основываясь на журналах, которые я видел, я считаю, что буферизация nginx препятствовала правильной передаче некоторых сообщений между клиентом / сервером.