Может ли nginx использоваться в качестве обратного прокси для серверного websocket-сервера?
мы работаем над приложением Ruby on Rails, которое должно использовать преимущества HTML5 websockets. На данный момент у нас есть два отдельных "сервера", так сказать: наше основное приложение работает на nginx+passenger и отдельный сервер, использующий Pratik Naik's судороги framework (который работает на тонкий) для обработки соединений websocket.
В идеале, когда придет время для развертывания, у нас будет приложение rails, работающее на nginx + passenger, и сервер websocket быть проксированным за nginx, поэтому нам не нужно, чтобы сервер websocket работал на другом порту.
проблема в том,что в этой настройке кажется, что nginx закрывает соединения слишком рано. Соединение успешно установлено к тонкому серверу, после этого немедленно закрыто с кодом 200 ответов. Мы предполагаем, что nginx не понимает, что клиент пытается установить долгосрочное соединение для трафика websocket.
правда, я не все, что подкованный с конфигурацией nginx, так можно ли даже настроить nginx в качестве обратного прокси для сервера websocket? Или мне нужно ждать, пока nginx предложит поддержку для нового рукопожатия websocket? Предполагая, что наличие сервера приложений и сервера websocket, прослушивающего порт 80, является требованием, может ли это означать, что я должен иметь тонкий запуск на отдельном сервере без nginx впереди?
заранее спасибо за любые советы или предложения. :)
-Джон
7 ответов
вы не можете использовать Nginx для этого в настоящее время[это не так], но я бы предложил посмотреть на HAProxy. Я использовал его именно для этой цели.
хитрость состоит в том, чтобы установить длинные таймауты, чтобы соединения сокетов не были закрыты. Что-то вроде:
timeout client 86400000 # In the frontend
timeout server 86400000 # In the backend
Если вы хотите служить, скажем, приложение rails и cramp на том же порту, вы можете использовать правила ACL для обнаружения соединения websocket и использовать другой бэкэнд. Таким образом, ваша конфигурация интерфейса haproxy будет выглядеть примерно как
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
Как насчет использования my модуль nginx_tcp_proxy_module?
этот модуль предназначен для общего TCP прокси с Nginx. Я думаю, что это также подходит для вебсокетов. И я просто добавляю tcp_ssl_module в ветку разработки.
nginx и (>= 1.3.13) теперь поддерживает обратное проксирование websockets.
# 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 соединения с восходящим (=backend), что означает, что нет keepalive возможно: Nginx выберет восходящий сервер, откроет соединение с ним, прокси, кэш (если вы хотите) и закроет соединение. Вот и все.
Это основная причина, по которой фреймворки, требующие постоянных подключений к бэкэнду, не будут работать через Nginx (нет HTTP/1.1 = нет keepalive и нет websockets, я думаю). Несмотря на это недостаток есть очевидное преимущество: Nginx может выбрать из нескольких восходящих потоков (баланс нагрузки) и отработки отказа на живой в случае, если некоторые из них не удалось.
редактировать: Nginx поддерживает HTTP 1.1 для бэкэндов и 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.