2012-11-28 126 views
2

我想反轉代理幾個socket.io websockets,也重寫了URL,以便我可以有一個前端服務器,可以連接到幾個後端tty.js實例。反向代理socket.io websocket與URL重寫

例如:

http://mysite.com/server1 reverse proxies to http://server1/ which is running tty.js 

http://mysite.com/server2 reverse proxies to http://server2/ which is running tty.js 

對於任何HTTP代理的老工作正常。然而,當我重寫的URL,而不是WebSocket的看起來像:

http://mysite.com/server1/socket.io/1/?t=1354135029745 -> http://server1/socket.io/1/?t=1354135029745 

它看起來像:

http://mysite.com/socket.io/1/?t=1354135029745 

這當然得不到處理。我假設重寫發生,所以套接字假定它的「連接」是在/socket.io/1/?t=1354135029745而不是/server1/socket.io/1/?t=1354135029745

有沒有某種方式做網址重寫以及代理websocket?

到目前爲止,我已經嘗試了使用TCP代理模塊的Varnish,node-http-proxy和Nginx,並且我一直無法弄清楚如何使其工作。

現在我的上光油的配置是這樣的:

backend backend1 { 
    .host = "1.1.1.1"; 
    .port = "8080"; 
    .connect_timeout = 1s; 
    .between_bytes_timeout = 60s; 
    .max_connections = 800; 
} 

backend backend2 { 
    .host = "2.2.2.2"; 
    .port = "8080"; 
    .connect_timeout = 1s; 
    .between_bytes_timeout = 60s; 
    .max_connections = 800; 
} 

sub vcl_recv { 
    set req.grace = 120s 
    if(req.url ~ "^/server1/") { 
     set req.url = regsub(req.url, "^/server1/", "/"); 
     set req.backend = backend1; 
     return(pipe); 
    } 
    if(req.url ~ "^/server2/") { 
     set req.url = regsub(req.url, "^/server2/", "/"); 
     set req.backend = backend2; 
     return(pipe); 
    } 
} 

sub vcl_pipe { 
    if(req.http.upgrade) { 
     set bereq.http.upgrade = req.http.upgrade; 
    } else { 
     set bereq.http.connection = "close"; 
    } 
    return(pipe); 
} 

我不得不離開了強制性:

if(req.url ~ "^/socket.io/") { 
    set req.backend = backend1; 
    return(pipe); 
} 

,因爲我有多個後端。有沒有辦法讓這個工作使用node-http-proxy,Nginx或Varnish?或者,如果沒有這些能力,是否會像haproxy或其他任何東西能夠?

我的第一個傾向是設置一個自定義標題,所以當URL被重寫時,它知道它應該打哪個後端,但我不確定是否/如何工作。

編輯1:我能夠通過也拉動req.http.referer和添加排序的解決這個問題,要在socket.io聲明:

if(req.url ~ "^/socket.io/" && req.http.referer ~ "server1"){ 
    set req.backend = backend1; 
    return(pipe); 
} 

但是這似乎有點靠不住並且似乎將socket.io恢復爲xhr輪詢,這不是理想的,而是比沒有更好的。

編輯2:經過幾個後端測試之後會發生什麼情況一旦長時間輪詢開始,它將打破代理的其餘部分。當我刷新頁面現在反向代理,而不是去:

http://mysite.com/server1 -> http://server1 

雲:

http://mysite.com/ -> http://server1 

,直到我重裝清漆,然後返回。

回答

0

最有可能你還需要改變Host:頭以及在vcl_recv()

sub vcl_recv { 
    set req.grace = 120s 
    if(req.url ~ "^/server1/") { 
     set req.url = regsub(req.url, "^/server1/", "/"); 
     set req.http.host = "server1"; 
     set req.backend = backend1; 
     return(pipe); 
    } 
    if(req.url ~ "^/server2/") { 
     set req.url = regsub(req.url, "^/server2/", "/"); 
     set req.http.host = "server2"; 
     set req.backend = backend2; 
     return(pipe); 
    } 
} 

這應該照顧你最初的問題的。

但是,在Varnish中使用管道有它可能需要考慮的缺陷。其中最重要的是缺少X-Forwarded-For header after the first request