socket.io分布式

socket.io是目前较为流行的web实时推送框架,其基于nodejs语言开发,底层用engine.io实现。 借助nodejs语言异步的特性,其获得了不错的性能。但单个实例的socket.io依然承载能力有限,最多只能容纳3000个long-polling方式的客户端进行连接。

将socket.io进行分布式扩展的难点有两处:

1. 进行负载均衡时客户端必须保证始终连到一个节点上

     如果客户端采用long-polling长轮训方式进行连接,则每次轮训都会产生一个新的请求,若不进行限制。就有可能连接到集群内新的 socket.io节点上,导致异常的发生。

     解决方法:使用nginx的ip_hash实现session sticky ,让客户端始终连接到集群内一台节点上。

2. 多个实例之间的消息推送

     当集群内某台节点想要向连接到集群的所有客户端发送消息时,某些客户端因为负载均衡时ip_hash可能被分配到了其他的节点上,这时就需要向其他节点发布推送消息,让其他节点的同时向客户端进行推送。

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

上图是采用该架构的一个聊天服务器集群示例,每个chatnode相当于一个socket.io实例,其中的chatModule负责客户端连接,adminModule负责聊天服务器的管理功能。

adminnode作为整个集群的管理节点,通过redis的消息订阅功能来与各个chatnode通信, 并通过开放http接口来与外部系统进行交互。

准备安装的软件:

nginxnodejsredis以及一个socket.io应用,如一个聊天服务器,例子请见官网这里

具体步骤:

1.将socket.io应用部署成两个实例,如在同一台主机上为每个实例分配不同的端口号4000, 5000:

[js] view plain copy

  1. http.listen(4000, function(){
  2. console.log(‘listening on *:4000‘);
  3. });

2.配置nginx文件,设置负载均衡proxy

upstream chat_nodes {
        ip_hash;
        server 127.0.0.1:4000;
        server 127.0.0.1:5000;
}

以及反向代理设置 (注意为了支持websocket协议,需将nginx升级至1.3.12版本以上

location / {
        proxy_pass              http://chat_nodes;
        proxy_set_header        Upgrade $http_upgrade;
        proxy_set_header        Connection "upgrade";
        proxy_http_version      1.1;
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }

完成配置后,重启nginx。

3.安装nodejs模块 socket.io-redis

sudo npm install socket.io-redis

4.在原来socket.io应用中初始化io的位置加入io的redis适配器:

[js] view plain copy

  1. var redis = require(‘socket.io-redis‘);
  2. io.adapter(redis({ host: ‘localhost‘, port: 6379 }));

5. 重启各个socket.io应用,进行测试。

其他注意点:

    • 由于nginx的反向代理机制和socket.io的自动重连机制,上述架构还具备高可用的特性,即当某个节点down机时,原先连接到该节点上的客户端会自动重连至其它节点上。
    • 节点的数量可以随时增减,不需要暂停服务,只需修改nginx配置即可。
    • nginx的ip_hash是基于ip的前三段进行计算的,也就是说ip只有D段不同的两台客户端一定会连接到同一台服务器上,这点测试的时候需要注意。
    • 可以通过redis的订阅发布服务来实现其他系统同集群的通信,完成集群的管理工作。
    • 由于是分布式环境,所以节点内存中存储的信息(如用户、房间信息)可以考虑持久化到redis或mongodb中。
时间: 2024-10-06 03:38:46

socket.io分布式的相关文章

socket.io与sticky-session, 多个socket.io实例带来的问题

websocket的出现使得从服务器向浏览器推送数据更加容易.但是低版本的浏览器不支持websocket,这时socket.io出现了. 使用socket.io的应用在支持websocket的浏览器运行的时候使用websocket,而在低版本的浏览器中则使用传统的方式与服务器交互(例如long-polling及其他的方式). long-polling的应用实现方式是这样的,客户端向服务器端发起请求,服务器端不会马上返回,而是保持这个连接直到服务器需要推送信息给客户端时,才返回给客户端数据.客户端

socket.io对IE8的支持

默认下载了最新版的socket.io,版本号是1.7.2,对IE8的支持不好,反正在IE8下收发消息都不行.在网上查了很多资料,都解决不了IE8的问题,崩溃. 最后用了一个大家比较认可的版本1.0.6,可以支持IE8: 卸载socket.io npm uninstall socket.io 安装1.0.6版本的socket.io npm install [email protected] 后面的一些版本没有一一的去试,下了一个1.3.7版本的,还是可以支持收发消息的,只是发现IE8在关闭窗口时,

Socket.IO初探

建立Server //server.jsvar io = require('socket.io')(80); var chat = io .of('/chat') //设定命名空间 .on('connection', function (socket) { socket.emit('a message', { //这个只会发送给自己的socket that: 'only' , '/chat': 'will get' }); chat.emit('a message', { //全局发送 ever

【socket.io研究】0.前提准备

WebSocket出现之前,web实时推送,一般采用轮询和Comet技术(可细分为长轮询机制和流技术两种),需要大量http请求,服务器受不了.HTML5定义了WebSocket协议,基于TCP协议,由通讯协议和编程API组成,在浏览器和服务器之间建立双向连接,以基于事件的方式,赋予浏览器实时通讯的能力. 建立WebSocket连接的过程是浏览器首先发起一个http请求,在请求头中附带着“Upgrade: WebSocket”头信息,表名申请协议升级,服务器解析后产生应答信息,服务器与客户端的W

【socket.io研究】2.小试牛刀

1.建立个项目,也就是文件夹,这里使用testsocket 2.创建文件package.json,用于描述项目: {     "name":"testsocket",     "version":"0.0.1",     "description":"my first nodejs app",     "dependencies":{         "ex

使用Node.js的socket.io模块开发实时web程序

首发:个人博客,更新&纠错&回复 今天的思维漫游如下:从.net的windows程序开发,摸到nodejs的桌面程序开发,又熟悉了一下nodejs,对“异步”的理解有了上上周对操作系统的学习而更能理解.然后发现了Node.js中的socket.io这个模块,又觉得跟前几天用.net做客户端的socket游戏了.技术世界,兜兜转转,相逢一笑,疑是故人. socket.io用来做实时web程序,解决之前的B/S程序只有无状态连接,特定需求还需要用长连接这种“奇技淫巧”的问题.当然,这是html

node+express+socket.io制作一个聊天室功能

首先是下载包: npm install express npm install socket.io 建立文件: 服务器端代码:server.js 1 var http=require("http"); 2 var express=require("express"); 3 var sio=require("socket.io"); 4 5 var app=express(); 6 app.use(express.static(__dirname+

[Node.js] Level 6. Socket.io

6.2 Setting Up socket.io Server-Side So far we've created an Express server. Now we want to start building a real-time Q&A moderation service and we've decided to use socket.io. Using the http module, create an new http server and pass the expressapp

nodejs socket.io

今天练习使用nodejs socket.io实现聊天室功能 已经做到功能: 1.自己发送信息在聊天室里出现: 2.自己的信息显示"我:",其他人的信息显示其id: 3.进入退出聊天室会有系统提醒: 想做的功能: 1.根据id进行1对1的聊天: 2.创建组进行小范围讨论: 3.在bootstap里找个好看的prompt弹窗: 经验总结: 1.nodejs 中 express跟http的关系似乎像 jq和js一样,express可以替代http var express = require(