我正在尝试反向代理几个socket.io websockets并重写URL,以便我可以拥有一个可以连接到多个后端tty.js实例的前端服务器。
例如:
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
有没有办法进行URL重写以及代理websocket?
到目前为止,我已经使用TCP代理模块尝试了Varnish,node-http-proxy和Nginx,但我还没弄清楚如何让它工作。
现在我的Varnish配置看起来像:
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 :(得分: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。