socketio集群官方文档

6 篇文章 2 订阅
1 篇文章 0 订阅

粘性负载平衡

如果计划在不同进程或计算机之间分配连接负载,则必须确保与特定会话ID关联的请求连接到发起它们的进程。

这是由于某些传输,如XHR轮询或JSONP轮询依赖于在“套接字”的生命周期内触发多个请求。未能启用粘性平衡将导致可怕的:

WebSocket握手期间出错:意外的响应代码:400

这意味着升级请求被发送到不知道给定套接字ID的节点,因此发送HTTP 400响应。

为了说明为什么需要这样做,请考虑向所有连接的客户端发送事件的示例:

io.emit('hi','all sockets');

有些客户可能会有一个活跃的双向通信渠道,就像WebSocket我们可以立即写入,但其中一些可能正在使用长轮询。

如果他们使用长轮询,他们可能会或可能不会发送我们可以写入的请求。他们可能“介于”这些请求之间。在这些情况下,这意味着我们必须在此过程中缓冲消息。为了让客户端在发送请求时成功声明这些消息,最简单的方法是让他连接到路由到同一个进程。

如上所述,WebSocket传输没有此限制,因为底层TCP连接在客户端和给定服务器之间保持打开。这就是为什么您可能会找到一些仅使用WebSocket传输的建议:

常量客户= 10(“https://io.yourhost.com”,{ //警告:在这种情况下,不存在回退到长轮询   传输:[ “的WebSocket” ] //或[“的WebSocket”,' polling'],这是同样的事情 })
  


两者都意味着当无法建立websocket连接时,长轮询没有FALLBACK,这实际上是Socket.IO的关键特性之一。在这种情况下,您应该考虑使用原始WebSocket,或者像robust-websocket这样的瘦包装器。

要实现粘性会话,有两个主要解决方案:

  • 根据客户的起始地址路由客户端

  • 基于cookie路由客户端

NginX配置

在文件的http { }部分中nginx.conf,您可以声明一个upstream包含Socket.IO进程列表的部分,以便在以下各项之间平衡负载:

http { server { listen 3000 ; server_name io.yourhost.com;
  
     
    

    location / { proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for ; proxy_set_header Host $ host ;
      
      

      proxy_pass http:// nodes;

      #enable WebSockets proxy_http_version 1。1 ; proxy_set_header升级$ http_upgrade ; proxy_set_header连接“升级” ;     }   }
       
      
      



  上游节点{ #启用基于IP     ip_hash的粘性会话 ;
    


    服务器 app01:3000 ; 服务器 app02:3000 ; 服务器 app03:3000 ;   } }
    
    


请注意ip_hash指示连接将是粘滞的指令。

确保您还在worker_processes最顶层配置以指示NginX应该使用多少工作人员。您可能还想调整块中的worker_connections设置events { }

Apache HTTPD配置

标题添加Set-Cookie “SERVERID = sticky。%{BALANCER_WORKER_ROUTE} e; path = /” env = BALANCER_ROUTE_CHANGED

<Proxy“balancer:// nodes_polling”> BalancerMember “http:// app01:3000” route = app01 BalancerMember “http:// app02:3000” route = app02 BalancerMember “http:// app03:3000” route = app03 ProxySet stickysession = SERVERID </ Proxy>
     
     
     
    


<Proxy“balancer:// nodes_ws”> BalancerMember “ws:// app01:3000” route = app01 BalancerMember “ws:// app02:3000” route = app02 BalancerMember “ws:// app03:3000” route = app03 ProxySet stickysession = SERVERID </ Proxy>
     
     
     
    


RewriteEngine  On 
RewriteCond %{HTTP:Upgrade} = websocket [NC] 
RewriteRule /(.*)balancer:// nodes_ws / $ 1 [P,L] 
RewriteCond %{HTTP:Upgrade}!= websocket [NC] 
RewriteRule /(.* )balancer:// nodes_polling / $ 1 [P,L]

ProxyTimeout 3

HAProxy配置

#参考:http://blog.haproxy.com/2012/11/07/websockets-load-balancing-with-haproxy/

listen chat 
  bind *:80个
  default_backend节点

后端节点
  选项httpchk HEAD /健康
  http检查期望状态200 
  cookie io前缀间接nocache#使用握手
  服务器上设置的`io` cookie app01 app01:3000检查cookie app01 
  服务器app02 app02:3000检查cookie app02 
  服务器app03 app03:3000检查cookie app03

使用Node.JS群集

就像NginX一样,Node.JS通过该cluster模块提供内置的集群支持。

Fedor Indutny创建了一个名为粘性会话的模块,确保文件描述符(即:连接)基于原始路由remoteAddress(即:IP)进行路由。请注意,这可能会导致路由不平衡,具体取决于散列方法。

您还可以根据群集工作程序ID为群集的每个工作人员分配不同的端口,并使用上面可以找到的配置平衡负载。

在节点之间传递事件

现在你有多个Socket.IO节点接受连接,如果你想向每个人(甚至某个房间里的每个人)广播事件,你需要一些在进程或计算机之间传递消息的方法。

负责路由消息的接口就是我们所说的Adapter。您可以在socket.io-adapter之上实现自己的(通过继承它),或者您可以使用我们在Redis上提供的那个:socket.io-redis

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

然后是以下电话:

io.emit('hi','all sockets');

将通过Redis 的Pub / Sub机制广播到每个节点。

注意:使用Redis适配器时仍需要粘性会话。

如果您想从nonsocket.io进程向它传递消息,您应该查看“从外部世界发送消息”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值