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;
}
以上配置测试是可用的。
其中最主要的是“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了。
花了点时间才找出解决办法,特在此记录一下,也希望能给后面有同样问题的朋友一点参考:
先贴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了。
相关文章推荐
- Nginx负载均衡 后端服务器怎么共享Session 问题
- 阿里云部署 Flask + WSGI + Nginx 详解
- Nginx防蜘蛛爬虫处理
- Nginx配置性能优化
- Nginx Rewrite规则初探
- Nginx配置&负载均衡实战
- Nginx与PHP(FastCGI)的安装、配置与优化
- 基于nginx和uWSGI在Ubuntu上部署Django
- nginx实现读写分离
- 终止所有nginx进程
- nginx日志轮询
- nginx主流程
- Nginx-Squit
- 如何正确配置Nginx+PHP
- nginx实现缓存功能
- (负载均衡)nginx+keepalive
- Nginx中Laravel的配置
- centos安装nginx
- nginx配置proxy_pass代理转发
- nginx配置文件中文详解