您的位置:首页 > 运维架构 > Nginx

nginx如何配置负载多个nodejs+socketio服务器

2015-09-30 10:40 766 查看
之前项目中有一个消息推送的模块,采用的是nodejs+socketio+redis的框架做的,打算用nginx去负载一下,结果在配置过程中发现客户端浏览器通过nginx与nodejs服务器建立的socket连接会一直中断重连,如此反复。

花了点时间才找出解决办法,特在此记录一下,也希望能给后面有同样问题的朋友一点参考:

先贴nginx.conf中的核心配置:

//配置要负载的几台机器

upstream io_nodes {

ip_hash;

server 192.168.0.101:3001 weight=1 max_fails=2 fail_timeout=30s;

server 192.168.0.101:3002 weight=1 max_fails=2 fail_timeout=30s;

server 192.168.0.101:3003 weight=1 max_fails=2 fail_timeout=30s;

}

//针对“/nodejs”的请求采用"io_nodes"负载
location /nodejs {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://io_nodes; }


以上配置测试是可用的。

其中最主要的是“ip_hash”这个配置,

配置它表示每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

////////////////////////////////////

针对上面的问题,后期又有了新的发现:

推荐使用nginx的nginx-sticky-module模块替代ip_hash,采用ip_hash模式可能会超成负载不均,引用别人的话:

常见的有使用nginx自带的ip_hash来做,我想这绝对不是一个好的办法,如果前端是CDN,或者说一个局域网的客户同时访问服务器,导致出现服务器分配不均衡,以及不能保证每次访问都粘滞在同一台服务器。如果基于cookie会是一种什么情形,想想看, 每台电脑都会有不同的cookie,在保持长连接的同时还保证了服务器的压力均衡,nginx sticky值得推荐。

如果浏览器不支持cookie,那么sticky不生效,毕竟整个模块是给予cookie实现的.

/////////////////////////////////////////////////////////

在后面测试中,还发现有一个问题,补充一下:

打个比方,nginx后面负载了A、B、C三台nodejs服务器;

用户a与服务器A建立了socket连接,当需要向a用户推送消息时就有可能出现,请求被nginx随机分发到B或C服务器上,这时则无法将消息推送给a用户;

解决方案:使用redis的发布与订阅功能与socket.io-redis开源库,该库在节点向客户端群发消息时会将该消息发布到redis的订阅队列中,让其他节点能够订阅到该消息,从而实现节点间消息推送。

首先安装socket.io-redis;

npm install socket.io-redis

然后在nodejs 文件中加入:

var io = require(‘socket.io’)(3000);

var redis = require(‘socket.io-redis’);

io.adapter(redis({ host: ‘localhost’, port: 6379 }));

测试一下试试,OK了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: