2012-11-28 128 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