nginx 作为 NodeJS+socket.io 的代理:除了大消息外一切正常
Posted
技术标签:
【中文标题】nginx 作为 NodeJS+socket.io 的代理:除了大消息外一切正常【英文标题】:nginx as a proxy for NodeJS+socket.io: everything is OK except for big messages 【发布时间】:2013-05-08 18:28:42 【问题描述】:正如nginx's website 中解释的那样,我已将这些设置用于我的 nginx 以将 websockets 代理到 NodeJS 服务器:
location /socket.io/
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
一切正常,socket.emit() / socket.on() 互相发送消息;直到我发送了一条相当大的短信(26 kB 的 html)。
NodeJS 没有收到这条大消息(所以我猜是 nginx 方面的问题) nginx 日志没有错误 一旦客户端发送了这条大消息,NodeJS 将停止从该客户端接收 socket.io 的心跳。我做错了什么? 是否有我不知道的 nginx 设置?
【问题讨论】:
你用的是什么版本的nginx? 我使用的是 nginx/1.4.0 我在使用你的配置时遇到了这个问题:Uncaught TypeError: Cannot call method 'onClose' of null
【参考方案1】:
找到的“解决方案”是使用haproxy在nginx和NodeJS之间拆分tcp流。
这不是最优的,因为它在我们的堆栈中添加了另一个程序,但它完成了工作。
在我看来,nginx websocket 支持距离生产就绪还很远。
【讨论】:
【参考方案2】:尝试在您的配置中添加这些:
proxy_buffers 8 2m;
proxy_buffer_size 10m;
proxy_busy_buffers_size 10m;
原因:proxy_buffer 默认大小为 4K 或 8K。因此,在大消息导致缓冲区溢出后,它可能会丢弃这些连接。检查默认设置here,使其符合您的要求。
【讨论】:
相反,我会用proxy_buffering off
关闭代理缓冲。 Comet 不适用于 nginx 缓冲,我怀疑 WebSockets 也会有同样的问题。你会认为 nginx 会自动禁用缓冲,或者至少在需要时将其置于默认配置中,但我猜有足够多的人使用更大的缓冲区。如果你要走缓冲路线,你还应该添加类似large_client_header_buffers 8 32k;
的东西。有关示例配置,请参阅 this gist。以上是关于nginx 作为 NodeJS+socket.io 的代理:除了大消息外一切正常的主要内容,如果未能解决你的问题,请参考以下文章