Можно ли использовать Nginx в качестве обратного прокси для сервера Backend WebSocket?

StackOverflow https://stackoverflow.com/questions/2419346

Вопрос

Мы работаем над приложением Ruby on Rails, которое необходимо воспользоваться преимуществами HTML5 Webockets. На данный момент у нас есть два отдельных «серверов», так сказать: наше главное приложение, работающее на пассажире Nginx+, и отдельный сервер, использующий Pratik Naik Судороги структура (которая работает на Тонкий) для обработки соединений WebSocket.

В идеале, когда придет время для развертывания, у нас будет приложение Rails, работающее на пассажире Nginx+, и сервер WebSocket будет прокси -прокси, поэтому нам не нужно будет работать с сервером WebSocket на другом порту.

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

По общему признанию, я не совсем такой смекал с Nginx Config, так что можно ли даже настроить Nginx, чтобы выступить в качестве обратного прокси для сервера WebSocket? Или мне придется ждать, пока Nginx предложит поддержку новым вещам ручной работы Websocket? Предполагая, что наличие как сервера приложений, так и сервера WebSocket, прослушивания на порту 80, является требованием, это может означать, что я должен иметь тонкий запуск на отдельном сервере без nginx впереди?

Заранее спасибо за любые советы или предложения. :)

-Джон

Это было полезно?

Решение

Вы не можете использовать Nginx для этого в настоящее времяЭто больше неправда, но я бы посоветовал взглянуть на хапроки. Я использовал его именно для этой цели.

Хитрость заключается в том, чтобы установить долгие тайм -ауты, чтобы подключения к сокетам не были закрыты. Что-то типа:

timeout client  86400000 # In the frontend
timeout server  86400000 # In the backend

Если вы хотите обслуживать, скажем, приложение Rails и Cramp на том же порте, вы можете использовать правила ACL для обнаружения соединения WebSocket и использовать другой бэкэнд. Так что ваша конфигурация Haproxy Frontend будет выглядеть как

frontend all 0.0.0.0:80
  timeout client    86400000
  default_backend   rails_backend
  acl websocket hdr(Upgrade)    -i WebSocket
  use_backend   cramp_backend   if websocket

Для полноты бэкэнд выглядел как

backend cramp_backend
  timeout server  86400000
  server cramp1 localhost:8090 maxconn 200 check

Другие советы

Как насчет использования моего nginx_tcp_proxy_module модуль?

Этот модуль предназначен для общего прокси TCP с NGINX. Я думаю, что это также подходит для WebSocket. И я просто добавляю tcp_ssl_module в ветвь разработки.

nginx (> = 1.3.13) теперь поддерживает Обратный прокси -панель.

# the upstream server doesn't need a prefix! 
# no need for wss:// or http:// because nginx will upgrade to http1.1 in the config below
upstream app_server {
    server localhost:3000;
}

server {
    # ...

    location / {
        proxy_pass http://app_server;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_redirect off;
    }
}

Из коробки (т.е. официальные источники) Nginx может установить только подключения HTTP 1.0 с UPSTREAM (= Backend), что означает, что не возможно KeepAlive: Nginx выберет вверх по течению, откройте его, прокси, кеш (если хотите и закрыть соединение. Вот и все.

Это основополагающая структура причины, требующие постоянных соединений с бэкэнд, не будут работать через Nginx (нет http/1.1 = без Keepalive, и, я думаю, нет веб -кокеты). Несмотря на наличие этого недостатка, существует очевидная выгода: Nginx может выбрать из нескольких восходящих (баланс нагрузки) и отключения, чтобы оживить, если некоторые из них не удались.

Редактировать: Nginx поддерживает HTTP 1.1 Backends & Keepalive с версии 1.1.4. «Fastcgi» и «Proxy» поддержаны. Вот это документы

Для тех, кто задается вопросом о той же проблеме, Nginx теперь официально поддерживает HTTP 1.1 вверх по течению. См. Документация Nginx для "Keepalive" и "Proxy_http_version 1.1".

Как насчет Nginx с новым модулем HTTP Push: http://pushmodule.slact.net/. Анкет Он позаботится о жонглировании соединением (так сказать), о котором, возможно, придется беспокоиться с обратным прокси. Это, безусловно, жизнеспособная альтернатива WebSockets, которые еще не полностью в миксе. Я знаю, что разработчик модуля HTTP Push все еще работает над полностью стабильной версией, но она активна. Есть версии его, используемых в производственных кодовых базах. Цитировать автора «полезный инструмент с скучным именем».

Я использую Nginx, чтобы обратить вспять прокси на сервер в стиле комета с длинными подключениями к опросам, и он отлично работает. Убедитесь, что вы настроили Proxy_send_timeout и Proxy_read_timeout на соответствующие значения. Также убедитесь, что ваш внутренний сервер, который NGINX обеспечивает поддержку HTTP 1.0, потому что я еще не думаю, что прокси-модуль Nginx еще не делает HTTP 1.1.

Просто чтобы прояснить некоторую путаницу в нескольких ответах: KeepAlive позволяет клиенту повторно использовать соединение для отправки еще одного HTTP -запроса. Это не имеет никакого отношения к длинным опросам или открытым соединениям, пока не произойдет событие, о чем задавался первоначальный вопрос. Таким образом, это не имеет значения, чем прокси -модуль Nginx только поддерживает HTTP 1.0, который не имеет Keepalive.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top