当前位置:首页 > 云谷精选

WebSocket长连接怎么防止连接数被耗尽

admin2026年03月18日云谷精选28.64万
摘要:# 当WebSocket长连接变成“耗电狂魔”:你的服务器是怎么被拖垮的 前两天跟一个做在线教育的朋友聊天,他愁眉苦脸地说:“我们那个实时答题系统,一到高峰期就卡,用户老掉线。查了半天,CPU内存都正常,就是新用户死活连不上来。” 我问他:“你们用We…

当WebSocket长连接变成“耗电狂魔”:你的服务器是怎么被拖垮的

前两天跟一个做在线教育的朋友聊天,他愁眉苦脸地说:“我们那个实时答题系统,一到高峰期就卡,用户老掉线。查了半天,CPU内存都正常,就是新用户死活连不上来。”

我问他:“你们用WebSocket做长连接的吧?最大连接数设了多少?”

他愣了一下:“这个……没专门设过,服务器默认的。”

得,问题八成就在这儿了。 很多团队上WebSocket的时候,光顾着高兴“终于能实时推送了”,却忘了长连接这玩意儿,本质上是在服务器上开了个长期占着的“包间”。包间数量有限,来的人多了,后来的就只能排队——或者直接被拒之门外。

一、连接数耗尽,比你想象中来得快

先别急着翻文档查配置,咱们算笔简单的账。

假设你用的是一台常见的4核8G云服务器,跑着Nginx和Node.js(或者其他语言的服务)。理论上,单个进程能支撑的WebSocket连接数,受限于文件描述符限制内存

Linux系统默认给单个进程的文件描述符限制通常是1024。就算你调高了系统级限制,比如调到65535,你猜猜一个8G内存的服务器,纯维持WebSocket连接(不算业务逻辑),能撑多少?

一个空闲的WebSocket连接,大概占20-30KB内存。 听着不多对吧?那我们来算:

  • 8G内存,留一半给系统和业务,剩4G(约4000MB)给连接。
  • 4000MB / 30KB ≈ 13.3万连接

看起来不少?但这是理想状态。实际上,一旦有消息收发,内存占用会涨,CPU要处理心跳、解码。而且,连接不是均匀来的——搞个活动,瞬间涌进来几万人,连接池一下就满了。更可怕的是,如果遇到恶意攻击,对方用脚本批量建连接,只连不发,专占坑位,你的正常用户瞬间就被挡在门外。

这感觉就像:你开了个网红餐厅,突然来了100个“顾客”,每人占一张桌,只点一杯白水坐一天。真正的食客?对不起,没位置了。

二、防耗尽,不是简单调个参数就行

很多人第一反应是:“那把最大连接数调大不就行了?”

真这么简单就好了。 盲目调大,就像为了应对洪水,把堤坝无限加高——最后洪水没来,堤坝自己先塌了(内存溢出,服务器崩溃)。你得有一套组合拳。

1. 设个“包间”使用规则(连接限制与超时)

首先,每个服务端必须设置明确的连接数上限。这个上限不是拍脑袋定的,要根据压测结果来。比如你的服务器压测到12万连接时响应明显变慢,那就设个10万的安全阈值。

其次,给连接加上“最长包厢时间”。也就是心跳超时机制。WebSocket本身没有强制心跳,但你需要自己实现。客户端每隔一段时间(比如30秒)发个心跳包(ping/pong),如果超时(比如90秒)没收到,服务端主动断开。这样能清理掉那些断了线但没正常关闭的“僵尸连接”。

// 一个简单的Node.js WS服务端心跳示例
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws, req) {
  ws.isAlive = true;

  ws.on('pong', () => {
    ws.isAlive = true; // 收到pong,标记为活跃
  });

  // ... 你的业务逻辑
});

// 每30秒检查一次
setInterval(() => {
  wss.clients.forEach((ws) => {
    if (ws.isAlive === false) {
      return ws.terminate(); // 超时了,断开
    }
    ws.isAlive = false;
    ws.ping(); // 发送心跳探测
  });
}, 30000);

2. 别让“占座党”得逞(IP与Session限流)

针对恶意连接,光超时不够,得从源头控制。

  • IP级连接数限制:同一个客户端IP,限制其最大并发连接数。比如,一个IP最多同时保持10个WebSocket连接。这能有效防止单IP用脚本疯狂建连。Nginx层面就可以做:
    # 在Nginx配置中,使用limit_conn模块
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn perip 10; # 每个IP同时最多10个连接
  • 用户级连接数限制:如果用户已登录,可以用userId来限制。一个用户账号,在同一设备类型上,原则上只保持1个活跃连接。新连接建立时,踢掉旧连接。避免用户自己“左右互搏”。

3. 准备个“备用大厅”(水平扩展与负载均衡)

单台服务器总有瓶颈。真正的解决方案是别把鸡蛋放一个篮子里。

通过负载均衡(如Nginx的ip_hash或一致性哈希),将WebSocket连接分散到多台后端服务器上。这样,每台服务器的连接数上限就成了集群的总上限。假设单台限10万连接,5台服务器就能撑50万。

这里有个关键细节:会话粘滞(Session Affinity)。因为WebSocket是长连接,一旦连接建立,后续通信必须落到同一台后端服务器,否则会找不到连接状态。所以负载均衡策略要选对,不能单纯轮询。

4. 雇个“保安队长”(接入层防护与WAF)

在流量进入你的WebSocket服务器之前,在前面加一层防护。

  • 高防IP/高防CDN:可以清洗掉大量协议畸形或流量异常的连接请求。很多DDoS攻击在协议层就被拦下了,到不了你业务服务器。
  • Web应用防火墙(WAF):可以配置针对WebSocket握手阶段的规则。比如,检查Upgrade头、Origin头是否合法,拦截那些连握手包都发不对的恶意脚本。
  • 慢连接攻击防护:有些攻击会建立连接后,以极慢的速度发送数据,耗尽你的线程池。在Nginx里可以配置client_body_timeoutclient_header_timeout,超时直接断。

三、那些“PPT里不提”的坑

说了这么多标准动作,我再分享几个实战中容易踩的坑,这些你在很多方案文档里可看不到。

坑1:心跳间隔太短,把自己“心跳”死了。 为了快速发现死连接,有人把心跳设成5秒一次。结果呢?连接数是稳了,但CPU开销暴涨,尤其是连接数大的时候,光处理心跳包就够忙了。心跳不是越短越好,要根据业务容忍度来。用户掉线30秒重连能接受吗?如果能,心跳设30-45秒完全没问题。

坑2:只防了建立,没防“保持”。 攻击者建立连接后,可以规规矩矩地发心跳,长期保持连接活跃,就是不干正事。这种“合法占用”更难防。这时候需要业务层监控:如果一个连接建立后,长时间(比如10分钟)没有任何业务消息交互,只有心跳,可以将其标记为“低活跃度连接”,在连接池紧张时优先回收其资源。

坑3:忽略客户端多样性。 移动端网络不稳定,用户进出电梯、切换WiFi/4G,都会导致连接断开重连。如果你的重连机制太激进(比如断开立即重连,无限重试),会在网络抖动时产生重连风暴,瞬间压垮服务器。好的做法是指数退避重连:第一次断,等1秒再连;再失败,等2秒、4秒、8秒……给服务器喘息之机。

四、说到底,这是一种“资源管理”思维

防止WebSocket连接数耗尽,归根结底是对有限服务器资源的一种精细化管理。它不像防CC攻击那样轰轰烈烈,更像是物业管理——得清楚有多少车位,谁在停车,停了多久,僵尸车怎么清理,访客怎么安排。

所以,下次当你设计一个实时应用时,别光盯着功能能不能跑通。在技术评审会上,多问一句:“咱们这个长连接,打算怎么管?”

方案再漂亮,真到流量洪峰来的那一刻,能稳稳接住的,永远是那些提前把“下水道”疏通好的团队。

行了,不废话了,如果你源站的长连接还在“裸奔”,我劝你今晚就加个班,把心跳和限流先配上。这玩意儿,平时感觉没用,真出了事,就是救命的。

扫描二维码推送至手机访问。

版权声明:本文由www.ysyg.cn发布,如需转载请注明出处。

本文链接:http://www.ysyg.cn:80/?id=460

“WebSocket长连接怎么防止连接数被耗尽” 的相关文章

CC放大攻击

**标题:CC放大攻击:你以为只是刷接口?它能把整个网站拖进泥潭** 如果你的网站或API接口最近突然变慢,甚至彻底打不开,查日志发现一堆奇怪的请求,指向某个你完全没听过的域名或IP,那可能不是简单的CC攻击。你遇到的,很可能是它的“威力加强版”——CC…

探究高防CDN中的分片重组防御算法:拦截利用IP分片漏洞的攻击

# 当攻击者把数据包“撕碎”扔过来,高防CDN是怎么一片片拼回去并抓住它的? 我前两天刚翻过一个客户的日志,挺有意思的。攻击流量看起来平平无奇,源IP也分散,但就是能把服务器CPU瞬间打满,然后瘫掉。查了半天,最后定位到问题——不是我们常见的CC洪水,而…

探究基于语义分析的攻击检测算法:识别隐藏在正常请求中的恶意载荷

# 当攻击穿上“隐身衣”:揪出藏在正常请求里的真家伙 我前两天帮一个做电商的朋友看后台日志,那叫一个头疼。流量看着挺正常,下单、加购、浏览,啥都有。可服务器CPU时不时就飙到100%,订单系统动不动就卡死。查了半天,你猜怎么着?那些看起来规规矩矩的“用户…

解析社交类应用在高并发访问下的 CDN 高防连接数优化技术

## 当你的社交App被“挤爆”时,别光骂服务器,可能CDN连接池先崩了 做社交应用的同行,估计都经历过这种心跳加速的时刻:一个热点事件突然引爆,或者某个大V随手转发,用户访问量瞬间像坐火箭一样往上窜。后台监控大屏一片飘红,服务器CPU拉满,紧接着就是用…

电商平台大促期间高防 CDN 的流量调度与边缘缓存优化方案

# 大促期间,你的网站别被流量“冲垮”了!聊聊高防CDN那点事 眼看又一个大促季要来了,老板们盯着KPI,运营们盘算着活动,技术团队呢?我估计不少朋友已经开始对着去年的监控图发愁了——**“去年双十一凌晨那波流量,差点把服务器干趴下,今年可咋整?”**…

分析自建高防 CDN 的性能瓶颈定位:内存、CPU 与网络带宽的监控

# 自建高防CDN,别让“性能瓶颈”成了你的软肋 说实话,这两年自己动手搭高防CDN的团队越来越多了。成本可控、配置灵活,听起来很美。但真跑起来,问题就来了——流量一上来,系统就卡成PPT,你根本不知道是哪个环节先“跪”的。 很多团队第一反应是:“加钱…