2010-03-10 3 views
35

Мы работаем над приложением Ruby on Rails, которое должно использовать веб-узлы html5. На данный момент у нас есть два отдельных «сервера», так сказать: наше основное приложение, работающее на nginx + пассажире, и отдельный сервер с использованием платформы Cramp Pratik Naik (которая работает на Thin) для обработки соединений в сети.Можно ли использовать nginx в качестве обратного прокси-сервера для серверного веб-сервера?

В идеале, когда придет время для развертывания, у нас будет приложение rails, работающее на nginx + пассажире, и сервер websocket будет проксимироваться за nginx, поэтому нам не нужно, чтобы сервер веб-сервера работал на другой порт.

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

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

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

-Джон

+1

Любой, кто до сих пор читает это, не принимает текущий ответ ниже. Прокси-модуль TCP работает хорошо, и ниже приведен ответ на ссылку о том, как его настроить: https://github.com/yaoweibin/nginx_tcp_proxy_module и http://www.letseehere.com/reverse-proxy-web-sockets – crockpotveggies

ответ

26

Вы не можете использовать Nginx для этого в настоящее время[it's not true anymore], но я хотел бы предложить, глядя на HAProxy. Я использовал его именно для этой цели.

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

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

Если вы хотите, чтобы служить сказать рельсы и приложение судороги на тот же порт можно использовать правила 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 
+1

Это замечательно, спасибо! Раньше я не использовал HAProxy, но мне всегда было нужно учиться. Похоже, у меня есть все основания для этого. :) –

+2

Этот ответ больше не верен (не удивительно, поскольку ему 3 года). Проверьте ответ @ mak дальше (в настоящее время), как настроить это на nginx> = 1.3.13 – toxaq

7

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

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

Редактировать: Nginx поддерживает HTTP 1.1 для backend & keepalive с версии 1.1.4. Поддерживаются «fastcgi» и «proxy» вверх по течению. Here it is the docs

+1

Понял, спасибо. По существу, то, что я пытаюсь сделать, в настоящее время невозможно. Может быть, когда-нибудь nginx будет поддерживать HTTP/1.1 keepalives для бэкэндов, но на данный момент мне придется придумать альтернативное решение. Спасибо за ответ. –

3

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

+0

Спасибо, это хорошее предложение. Мы фактически использовали этот самый модуль для достижения нажима на сервер какое-то время, но теперь мы хотим поддерживать двунаправленную связь ... И поскольку нам нужно только поддерживать браузеры webkit для нашего приложения, мы надеемся пойти с чистый подход к веб-раскладке. Но я ценю ответ! :) –

2

Я использую Nginx для обратного прокси-сервера для кометы сервера стиля с длинными избирательными соединениями и он прекрасно работает. Убедитесь, что вы настроили proxy_send_timeout и proxy_read_timeout соответствующие значения. Также убедитесь, что ваш серверный сервер, который nginx использует для проксирования, поддерживает http 1.0, потому что я не думаю, что прокси-модуль nginx делает http 1.1 еще.

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

12

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

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

+6

Вы ** думаете **, но не тестировали его с помощью WebSocket? – Jonas

+2

@ Jonas: Я не знаю, тестировал ли он это в то время, когда он сделал этот комментарий, но я могу подтвердить, что его TCP-прокси теперь явно поддерживает веб-узлы. –

+0

В этой статье объясняется, как настроить, протестировать и использовать модуль yaoweibin для размещения соединений Websocket: http://www.letseehere.com/reverse-proxy-web-sockets – natevw

5

Для тех, кто интересуется той же проблемой, nginx теперь официально поддерживает HTTP 1.1 вверх по течению. См. Документацию nginx для «keepalive» и «proxy_http_version 1.1».

+0

Да, но он не будет поддерживать веб-порты до версии 1.3. – toxaq

+0

Действительно, следует отметить, что он еще не сделал его в версии 1.3, хотя и выпущен. Их дорожная карта предоставит некоторую информацию о статусе внедрения Websocket (в настоящее время запланирована на 1.3.x): http://trac.nginx.org/nginx/roadmap –

10

nginx (>= 1.3.13) now supports обратные прокси-серверы.

# 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; 
    } 
} 
+0

@mark. Хотя это хорошо работает для http, у меня есть проблема с https. Я как-то получаю 301. Я успешно установил nginx с websocket на http, но через ssl я получаю t 301. https://github.com/websocket-rails/websocket-rails/issues/333 это проблема, которую я создал. Дайте мне знать, если вы можете помочь. благодаря –

Смежные вопросы