Frage

Wir arbeiten an einer Ruby on Rails-App, die HTML5-Websockets nutzen muss.Im Moment haben wir sozusagen zwei separate „Server“:Unsere Haupt-App läuft auf Nginx+Passenger und ein separater Server verwendet Pratik Naik Krampf Framework (auf dem ausgeführt wird). Dünn), um die Websocket-Verbindungen zu verwalten.

Im Idealfall würden wir bei der Bereitstellung die Rails-App auf Nginx+Passenger ausführen und der WebSocket-Server würde als Proxy hinter Nginx laufen, sodass wir den WebSocket-Server nicht auf einem anderen Port laufen lassen müssten.

Das Problem ist, dass Nginx in diesem Setup die Verbindungen zu Thin anscheinend zu früh schließt.Die Verbindung zum Thin-Server wird erfolgreich hergestellt und dann sofort mit dem Antwortcode 200 geschlossen.Wir gehen davon aus, dass Nginx nicht erkennt, dass der Client versucht, eine lang andauernde Verbindung für den Websocket-Verkehr herzustellen.

Zugegebenermaßen kenne ich mich mit Nginx-Konfigurationen nicht so gut aus. Ist es also überhaupt möglich, Nginx so zu konfigurieren, dass es als Reverse-Proxy für einen Websocket-Server fungiert?Oder muss ich warten, bis Nginx Unterstützung für die neuen Websocket-Handshake-Funktionen anbietet?Angenommen, dass sowohl der App-Server als auch der WebSocket-Server Port 80 überwachen müssen, könnte das bedeuten, dass ich Thin vorerst auf einem separaten Server ohne Nginx laufen lassen muss?

Vielen Dank im Voraus für Ratschläge oder Vorschläge.:) :)

-John

War es hilfreich?

Lösung

Sie können Nginx derzeit nicht dafür verwenden[es ist nicht mehr wahr], aber ich würde vorschlagen, sich HAProxy anzusehen.Ich habe es genau für diesen Zweck verwendet.

Der Trick besteht darin, lange Timeouts festzulegen, damit die Socket-Verbindungen nicht geschlossen werden.Etwas wie:

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

Wenn Sie beispielsweise eine Rails- und Cramp-Anwendung auf demselben Port bereitstellen möchten, können Sie ACL-Regeln verwenden, um eine Websocket-Verbindung zu erkennen und ein anderes Backend zu verwenden.Ihre Haproxy-Frontend-Konfiguration würde also ungefähr so ​​aussehen

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

Der Vollständigkeit halber würde das Backend so aussehen

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

Andere Tipps

Wie wäre es, wenn ich meine benutze nginx_tcp_proxy_module Modul?

Dieses Modul ist für allgemeine TCP -Proxy mit Nginx ausgelegt. Ich denke, es ist auch für Websocket geeignet. Und ich füge nur TCP_SSL_MODULE in den Entwicklungszweig hinzu.

nginx (> = 1.3.13) unterstützt jetzt Reverse Proxying 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;
    }
}

Aus dem Box (dh offizielle Quellen) kann nginx nur HTTP 1.0 -Verbindungen zu einem Upstream (= Backend) herstellen, was bedeutet ) und schließen Sie die Verbindung. Das ist es.

Dies ist der grundlegende Grund, warum Rahmenbedingungen, die anhaltende Verbindungen zum Backend erfordern, nicht über Nginx funktionieren (kein HTTP/1.1 = Keepalive und keine Websockets). Trotz dieses Nachteils gibt es einen offensichtlichen Vorteil: Nginx kann aus mehreren Upstreams (Lastbilanz) und einem Failover an lebendige Auswahl ausgewählt werden, falls einige von ihnen fehlgeschlagen sind.

Bearbeiten: Nginx unterstützt HTTP 1.1 für Backends & Keepalive seit Version 1.1.4. "Fastcgi" und "Proxy" stromaufwärts werden unterstützt. Hier sind es die Dokumente

Für alle, die sich über das gleiche Problem wundern, unterstützt Nginx jetzt offiziell HTTP 1.1 stromaufwärts. Siehe Nginx -Dokumentation für "Keepalive" und "proxy_http_version 1.1".

Wie wäre es mit Nginx mit dem neuen HTTP -Push -Modul: http://pushmodule.slact.net/. Es kümmert sich um die Verbindung, die sich (sozusagen) um Jonglieren handelt, über die man sich möglicherweise mit einem umgekehrten Proxy Sorgen machen muss. Es ist sicherlich eine praktikable Alternative zu Websockets, die noch nicht vollständig in der Mischung enthalten sind. Ich weiß, dass der Entwickler des HTTP -Push -Moduls immer noch an einer vollständig stabilen Version arbeitet, aber es befindet sich in aktiver Entwicklung. Es gibt Versionen, die in Produktionscodebasen verwendet werden. Um den Autor zu zitieren, "ein nützliches Werkzeug mit einem langweiligen Namen".

Ich verwende Nginx, um den Proxy auf einen Comet -Style -Server mit langen Umfragebehörungen umzukehren, und es funktioniert großartig. Stellen Sie sicher, dass Sie proxy_send_timeout und proxy_read_timeout mit entsprechenden Werten konfigurieren. Stellen Sie außerdem sicher, dass Ihr Back-End-Server, den Nginx ansieht, um HTTP 1.0 zu unterstützen, da ich nicht glaube, dass das Proxy-Modul von NGINX HTTP 1.1 noch tut.

Nur um eine gewisse Verwirrung in einigen Antworten zu beseitigen: Keepalive ermöglicht es einem Kunden, eine Verbindung wiederzuverwenden, um eine andere HTTP -Anfrage zu senden. Es hat nichts mit langen Umfragen oder Halten von Verbindungen zu tun, bis ein Ereignis auftritt, worüber die ursprüngliche Frage gestellt wurde. Es spielt also keine Rolle, als das Proxy -Modul von Nginx nur HTTP 1.0 unterstützt, was nicht auf Keepalive verfügt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top