【发布时间】:2012-06-25 13:03:03
【问题描述】:
nginx 是一个杀手级静态文件服务器。
它可以像this example 一样为node.js 提供服务,但方式有限。
但nginx 是apparently unable 以代理websockets。
我发现唯一可行的方法是按照 this article 使用 HAProxy 前端 - 但它是从 2011 年 10 月 6 日开始的。
这个必须是一个常见的问题,但我没有找到一个非常常见的解决方案。
解决方案
(请参阅https://github.com/bangkok-maco/barebone-node了解完整的解决方案和详细信息)
ip 测试架构:
- 127.0.0.12 - www.chat.nit - 公共,在 /etc/hosts 和 haproxy 中
- 127.0.1.12 - 内部 nginx 网络服务器
- 127.0.2.12 - 内部聊天服务 node.js socket.io
/etc/haproxy/haproxy.cfg:
global
maxconn 4096
nbproc 2
daemon
# user nobody
log 127.0.0.1 local1 notice
defaults
mode http
# listen on 127.0.0.12:80
frontend app
bind 127.0.0.12:80
mode tcp
timeout client 86400000
default_backend www_backend
acl is_chat hdr_dom(Host) chat
acl is_websocket path_beg /socket.io
use_backend chat_socket_backend if is_websocket is_chat
tcp-request inspect-delay 500ms
tcp-request content accept if HTTP
# ngnix on 127.0.1.12:80
backend www_backend
balance roundrobin
option forwardfor
mode http
option httplog
option httpclose
timeout server 30000
timeout connect 4000
server w1 127.0.1.12:80 weight 1 maxconn 1024 check
# node (socket.io) on 127.0.2.12:80
backend chat_socket_backend
balance roundrobin
mode http
option httplog
option forwardfor
timeout queue 5000
timeout server 86400000
timeout connect 86400000
timeout check 1s
no option httpclose
option http-server-close
option forceclose
server s14 127.0.2.12:8000 weight 1 maxconn 1024 check
/etc/nginx/sites-enabled/www.chat.nit
server {
listen 127.0.1.12:80;
root /data/node/chat;
index client.html;
server_name www.chat.nit;
# favicon.ico is in /images
location = /favicon.ico$ { rewrite /(.*) /images/$1 last; }
# standard includes
location ^~ /(css|images|scripts)/ {
try_files $uri =404;
}
# html page (only in root dir)
location ~ ^/([-_a-z]+).html$ {
try_files $uri =404;
}
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/www;
}
}
聊天(node.js):server.js
var app = require('http').createServer()
, io = require('socket.io').listen(app);
app.listen(8000,'127.0.2.12');
io.sockets.on('connection', function(socket) {
...
};
聊天:client.html
<head>
<script src="/scripts/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://www.chat.nit:80');
...
</script>
</head>
注释:
-
将socket.io客户端js链接到
scripts/目录/.../scripts$ ln -s ../node_modules/socket.io/node_modules/socket.io-client/dist/socket.io
-
/etc/default/haproxy(与文本相反,必须设置为工作完全)
启用=1
此版本 haproxy 未记录。找到kvz's写了如何通过127.0.0.1使用
rsyslogd,但无法让它飞起来。这个解决方案是工作 - 不是系统管理员质量可以肯定。 (增强功能非常受欢迎。)
【问题讨论】:
-
实际上 HAProxy 正在工作。我正在使用它来代理 WebSockets,我对此非常满意。根据我的经验,代理 WebSockets(和其他请求)比“杀手级静态文件服务器”更重要,但实际上它取决于您的应用程序。此外,Node.js 不是一个糟糕的静态文件服务器(例如 Express 框架)——该技术与 nginx(异步单线程)非常相似。
-
您可以发布您的 HAProxy 配置作为答案吗?你知道是否可以在非 ws 的 nginx 和 ws/wss 的 node.js 之间拆分 HAProxy 的输出?
-
是的,拆分应该不是问题。毕竟ws/wss可以被
upgradeheader 识别。 -
您可能有兴趣查看tcp_proxy 的 Nginx,可以proxy websockets。
标签: node.js nginx websocket socket.io haproxy