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

之前项目中有一个消息推送的模块,采用的是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了。

—2017-04-12 发现有如下错误一直在请求——-

WebSocket connection to
‘ws://123.123.123.123:123/socket.io/?EIO=3&transport=websocket&sid=7NvWtwxN2lvBuVyS8tRk’
failed: Error during WebSocket handshake: Unexpected response code:
400

解决方案如下:
nginx.conf里面加入:

location / {
……….
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “Upgrade”; }

完整配置文件如下:

user  root;
worker_processes  8;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    #
    worker_connections  65535;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens   off;
    #控制服务器的hash表
    server_names_hash_bucket_size 128;

    #开启压缩功能
    gzip  on;
    gzip_http_version 1.1;
    gzip_vary on;
    gzip_comp_level 9;
    gzip_proxied any;
    gzip_types text/plain  text/css application/json  application/x-javascript text/xml application/xml application/xml+rss text/javascript application/x-shockwave-flash image/png image/x-icon image/gif image/jpeg;
    gzip_buffers 16 8k;


    #access_log  logs/access.log  main;
    error_log  /dev/null crit;
    access_log off;
    #开启sendfile功能
    sendfile        on;

    keepalive_timeout  600;

    upstream io_nodes { 
    ip_hash;
    server 111.17.117.36:3001 weight=1 max_fails=3 fail_timeout=30s;
    server 111.17.117.36:3002 weight=1 max_fails=3 fail_timeout=30s;
    #session_sticky;
    }


    server {
        listen       9000;
    server_name  localhost;

    location / {
                proxy_redirect          off;
                proxy_buffering off;
                proxy_set_header       Host $host:$server_port;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                client_max_body_size    10m;
                client_body_buffer_size 128k;
                proxy_connect_timeout   1000;
                proxy_send_timeout      1000;
                proxy_read_timeout      1000;
                proxy_buffer_size       256k;
                proxy_buffers           128 256k;
                proxy_busy_buffers_size 256k;
                proxy_temp_file_write_size 256k; 
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
        proxy_pass      http://io_nodes;    
       }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现nginx配置node socket.io vue的负载均衡,需要先安装nginx和node.js以及socket.io。 以下是简单的步骤: 1. 安装nginx 使用以下命令安装nginx: ``` sudo apt-get update sudo apt-get install nginx ``` 2. 配置nginx 在 /etc/nginx/conf.d/ 目录下创建一个新的配置文件,例如 socketio.conf,将以下内容粘贴到文件中: ``` upstream socketio_backend { ip_hash; server node1:3000; server node2:3000; } server { listen 80; server_name yourdomain.com; location / { proxy_pass http://socketio_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } ``` 这个配置文件设置了一个名为 socketio_backend 的负载均衡器,它将请求转发到两个不同的Node.js服务器,分别是 node1 和 node2,它们都运行在3000端口上。 3. 安装Node.js和socket.io 在 node1 和 node2 服务器上安装 Node.js 和 socket.io,使用以下命令: ``` sudo apt-get update sudo apt-get install nodejs sudo apt-get install npm sudo npm install socket.io ``` 4. 在Node.js中使用socket.io 在 Node.js 应用程序中使用以下代码启动 socket.io: ``` var io = require('socket.io')(3000); io.on('connection', function (socket) { console.log('a user connected'); }); ``` 这段代码启动了一个 socket.io 实例,并监听在3000端口上,当有一个新的客户端连接时,会在控制台输出“a user connected”。 在Vue.js中使用socket.io 在Vue.js应用程序中使用以下代码连接到socket.io: ``` import io from 'socket.io-client'; const socket = io('http://yourdomain.com'); ``` 这段代码连接到运行在yourdomain.com的socket.io服务器。 至此,你就可以在Vue.js应用程序中使用socket.io了,并且通过nginx实现了负载均衡。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值