2012-06-05 41 views
4

我正在使用websocket處理程序的龍捲風應用程序。我使用Supervisord運行應用程序的多個實例,但是我在加載平衡websocket連接時遇到了問題。使用HAProxy負載均衡與Tornado應用程序的WebSocket連接?

我知道nginx不支持處理開箱即用的websockets,但我按照http://www.letseehere.com/reverse-proxy-web-sockets的說明使用nginx tcp_proxy模塊來反向代理websocket連接。然而,這不起作用,因爲模塊無法路由websocket url(例如:ws:// localhost:80/something)。所以它不適用於我在我的Tornado應用中定義的URL路由。

從我對網絡的研究中,似乎HAProxy是負載平衡我的websocket連接的方式。但是,我無法找到任何體面的指導來設置HAProxy來負載均衡websocket連接,並且還能夠處理websocket URL路由。

我真的很感謝有關如何實現這一目標的一些詳細說明。我也對其他解決方案完全開放。

回答

5

在haproxy中實現WebSocket並不困難,儘管我承認在這方面找到doc並不容易(希望這個迴應會舉一個例子)。如果您使用haproxy 1.4(我認爲您是),那麼它就像任何其他HTTP請求一樣工作,而不必執行任何操作,因爲HTTP升級可以被haproxy識別。

如果你想WebSocket的流量引導到不同的農場比HTTP的休息,那麼你應該使用內容交換的規則,簡而言之就是:

 
frontend pub-srv 
    bind :80 
    use_backend websocket if { hdr(Upgrade) -i WebSocket } 
    default_backend http 

backend websocket 
    timeout server 600s 
    server node1 1.1.1.1:8080 check 
    server node2 2.2.2.2:8080 check 

backend http 
    timeout server 30s 
    server www1 1.1.1.1:80 check 
    server www2 2.2.2.2:80 check 

如果您使用1.5-dev的,你甚至可以指定「超時隧道」以使WS連接的超時時間大於普通HTTP連接的超時時間,這樣可以避免在客戶端使用過長的超時。

您還可以結合升級:WebSocket的+特定的URL:

 
frontend pub-srv 
    bind :80 
    acl is_websocket hdr(Upgrade) -i WebSocket 
    acl is_ws_url path /something1 /something2 /something3 
    use_backend websocket if is_websocket is_ws_url 
    default_backend http 

最後,請不要使用愚蠢的24小時空閒超時,我們有時會看到,它使絕對沒有 意義等待客戶端現在已經建立了會議24小時。網絡比80年代移動更多 ,連接是非常短暫的。你最終會得到許多FIN_WAIT插座 。目前的互聯網已經有10分鐘的時間了。

希望這有助於!

+0

感謝您提供詳細和翔實的回覆。我今天會試一試並回復。我知道你表達了你對高空閒超時的厭惡感,並且你的觀點對大多數應用程序都有意義。我實際上使用websockets在嵌入式設備和服務器之間創建通信。這個設備實際上永遠是永遠(理論上)。那麼有沒有辦法根本沒有超時? –

+0

@AmirR。我也希望實施類似的設置,希望聽到您採用上述答案的結果。 – skyork

+0

如果您想要(並且會收到警告),您可以禁用超時。但是,這總是一個設計錯誤,因爲您認爲設備永遠不會失敗/崩潰/重新啓動/斷開連接,這是100%錯誤。請記住,超時是爲了保護組件免受其他組件意外故障的影響。當你的設備出現故障時,你不想重新啓動haproxy來擺脫fantom連接,這是沒有意義的。 –

0

WebSockets不能很好地遍歷代理,因爲之後的握手他們沒有遵循正常的HTTP行爲。

嘗試使用WebSocket(wss://)協議(受保護的WS)。這將使用Proxy CONNECT API來隱藏WebSocket協議。

+0

所以你說,如果我使用WSS://然後就可以實現URL處理? –

+0

我不同意,事實上恰恰相反,握手是100%HTTP兼容的,並且是爲此設計的,但它使用了HTTP的升級功能,很多代理在過去並不關心實施這些功能。如果您的代理不支持升級機制,請向您的供應商提交錯誤報告,這對於修復網絡非常重要! –

+0

是的,Amir,WSS繞過了代理需要從升級中實現的邏輯。它使它無需任何干預就可以連接處理連接。 –

0

HTTP的nginx(僅nginx的V1。3+)

upstream chatservice { 
    #multi thread by tornado 
    server 127.0.0.1:6661; 
    server 127.0.0.1:6662; 
    server 127.0.0.1:6663; 
    server 127.0.0.1:6664; 
} 
map $http_upgrade $connection_upgrade { 
    default upgrade; 
    ''  close; 
} 

虛擬主機

server { 
    listen 80; 
    server_name chat.domain.com; 
    root /home/duchat/www; 
    index index.html index.htm; 

    location/{ 
      try_files $uri $uri/ @backend; 
    } 
    location @backend { 
      proxy_pass_header Server; 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_http_version 1.1; 
      proxy_set_header Upgrade $http_upgrade; 
      proxy_set_header Connection "upgrade"; 
      proxy_set_header Host $host; 
      proxy_pass http://chatservice; 
      internal; 
}