1.3 机器准备:CVM 规格与长连接
白板上线第三天,凌晨两点告警响了:八百个房间集体掉线,前端一片白屏。排查了两个小时才发现,不是服务挂了,是中间负载均衡的空闲超时设成了六十秒,而白板大部分时候没人画,连接静默了六十秒就被中间层掐掉了,前端还以为在线。这是长连接服务最典型的坑——「假在线」。本篇从规格怎么挑、长连接怎么开、超时怎么对齐三件事讲起,把这台后端的底座打牢,后面房间、广播、持久化都建立在「连接稳」之上。
规格怎么挑
先别急着买机器,把负载画像算清楚。长连接服务是「吃连接数」不「吃 CPU」的负载:一千个空闲房间的连接几乎不耗算力,但每个连接在服务端都占着一份会话对象——「这条连接是谁、在哪个房间、收到第几笔了」,全是内存里的状态。连接越多,内存越高,所以规格往内存上偏比堆 CPU 更划算。
| 场景 | 并发连接 | 推荐规格 | 说明 |
|---|---|---|---|
| 演示 / 测试 | 数百 | 1C2G / 2C4G | 单节点够用 |
| 小团队协作 | 千级 | 4C8G | 留内存给会话对象 |
| 中型协作 | 万级 | 8C16G + 多节点 | 需横向加会话共享 |
还有一笔容易被漏算的账:连接数不只是「在线用户数」,还要乘上「平均每人在几个房间」。一个团队的人可能同时在线两三个会议白板,实际连接数是用户数的两到三倍,机器按在线用户配就会配小。估算时建议直接按「在线用户 × 人均房间数」给连接数留余量,再落到规格上。
长连接的关键配置
长连接最怕的不是带宽,而是中间设备的空闲超时。云 CVM 前面通常还挂着一层负载均衡、前面还有 NAT 网关,它们对空闲 TCP 都设了超时,常见的在六十秒到三百秒之间。到点就把「看起来空闲」的连接掐了,而白板恰恰大部分时间不发消息,空闲连接就成了「静默受害者」。
所以要把全链路超时列成一张表对齐,让最紧的那一层喂住:
| 配置项 | 建议 | 原因 |
|---|---|---|
| 应用心跳间隔 | 小于最紧的网关超时,常见 30~45s | 让「空闲」连接保持「活跃」 |
| 心跳包 | 轻量 ping/pong,带时间戳 | 顺带测延迟 |
| 负载均衡会话保持 | 开,保持时长大于心跳周期 | 同连接稳定打同节点 |
| 超时阈值 | 前端、网关、应用三处一致 | 避免某一层先掐断 |
要点是找出全链路最紧的那一层,心跳间隔要小于它,其他层都比它宽松一档。三处不一致时,总有某一层先到点把连接静默杀掉,这就是「跑着跑着房间集体掉线」的根因。云服务器选型与长连接部署的完整对照,可参考 Node.js 云开发实战,规格与扩容线也可对照 轻量服务器建站 的成本视角。
端口与转发
WebSocket 在 HTTP 之上建连,走 80/443 即可,不必额外开端口;关键是让转发层支持 WebSocket 升级(Upgrade),否则连接建到一半被当普通 HTTP 处理就断了。用云服务器部署时,前面若挂负载均衡,记得在监听里勾选 WebSocket 支持。这一层配错的症状极隐蔽:本地连、线上断——开发机直连正常,一上负载均衡就建连失败,排查半天才定位到转发层没开 Upgrade。
规格之外的隐性成本
上面三张表都是「明账」,但还有几笔隐性成本,不预算就会在扩容时打脸。第一笔是会话共享的存储成本:单机内存里的会话对象,横向扩容后必须落到 Redis 做跨节点共享,连接数上千时这部分内存与网络往返会成为新瓶颈,规格里要把它算进去而不是事后补。第二笔是回放与快照的对象存储成本:白板操作日志与定期快照最终都写进 COS,连接数越大、在线越久,对象存储的容量与请求量随时间线性累积,上线前要按「每天每人多少笔 × 留存天数」给存储预算留足,别等账单爆了才反应过来。
| 隐性成本 | 触发条件 | 预算动作 |
|---|---|---|
| 会话共享存储 | 多节点横向扩容 | 预算 Redis 内存,随连接数线性 |
| 快照对象存储 | 在线时长与日志留存 | 预算 COS 容量与请求量,按天累积 |
| 网关连接数 | 高峰并发连接 | 预算 LB 并发连接与规格上限 |
这两笔成本都属于「慢变量」,短期内看不出来,长期必然显现,规划阶段就要纳入。更稳的做法是上线后每周看一次连接数与存储增长曲线,提前两周预判扩容时间点。
规格选型的自检三问
买机器前问自己三个问题,答不上来就先别下单。第一问:峰值连接数多少? 不是「注册用户数」,而是「高峰同时在线 × 人均房间数」,长连接规格跟着这个数字走。第二问:会话对象放哪? 单机内存只撑得住单节点,扩容就必然引入 Redis,规格表里要留出这份内存。第三问:挂了影响多大? 长连接服务是单点故障直达用户白屏的,关键场次要至少两节点起步,别为省一台机器的钱把可用性搭进去。
| 自检问题 | 常见答错 | 正确口径 |
|---|---|---|
| 峰值连接数 | 按注册用户配 | 高峰在线 × 人均房间 |
| 会话放哪 | 只想单机内存 | 扩容即上 Redis |
| 故障半径 | 没想过单点 | 关键场次至少双节点 |
三问答完,规格、存储、可用性三件事就都落到纸面上了,买机器这件事才真正有依据。还有一个经验之谈:规格先按双节点起步,哪怕初期流量只够单机。原因是长连接服务的扩容不像无状态服务那么平滑——加节点要牵动会话共享和房间重连,临时抱佛脚必然出故障。一开始就双节点,扩容路径是「加机器」而不是「改架构」,风险低得多。这笔多出来的机器钱,买的是「扩容时不改架构」的保险,对长连接服务格外值。规格定档后,把「连接数、内存、节点数」三个数字写进部署文档,后面扩容时直接对照修订,不用每次重新估算。
本批推荐:腾讯云云产品合集特惠,云服务器、负载均衡、数据库、对象存储一次配齐,长连接与静态加速都能搭好。
连接数估算的实战口径
说了这么多原则,给一个可以直接套用的估算示例。假设产品目标是「中型团队协作」:高峰在线 500 人,人均同时开 2 个白板,每人每秒平均 2 笔。那么峰值连接数约 1000 条,事件峰值约 2000 笔/秒(扇出后按房间规模再乘)。对照规格表落在 4C8G 单节点偏紧、双节点有余量的区间,会话共享上一台小规格 Redis 即可。这只是起点,上线后要按真实曲线回校:预估是用来兜底的,实测才是用来扩容的。
| 估算项 | 示例值 | 推导 |
|---|---|---|
| 峰值连接数 | ~1000 | 高峰在线 500 × 人均 2 房间 |
| 事件峰值 | ~2000 笔/秒 | 500 人 × 2 笔 |
| 扇出后事件 | 看房间规模 | 房间越大倍数越高 |
| 规格落点 | 4C8G × 2 | 连接数偏内存,双节点保可用 |
这个估算里最容易漏掉的是扇出放大:2000 笔/秒是「收到」的量,服务端真正要推出去的事件数还要乘上「房间内其他人数」。同样是 2000 笔,10 人房间推 2 万次、100 人房间推 20 万次,机器压力差一个数量级。所以规格不仅要看「收多少」,更要看「推多少」,后者才是长连接服务真正的成本中心。压测时也要按「推」的量级来打,而不是只打「收」,否则上线遇到热房间还是会塌。这一节给的数字是示例,各团队套自己的业务画像重新算一遍,别忘了把扇出倍数写进估算表。
端口与转发
WebSocket 在 HTTP 之上建连,走 80/443 即可,不必额外开端口;关键是让转发层支持 WebSocket 升级(Upgrade),否则连接建到一半被当普通 HTTP 处理就断了。用云服务器部署时,前面若挂负载均衡,记得在监听里勾选 WebSocket 支持。这一层配错的症状极隐蔽:本地连、线上断——开发机直连正常,一上负载均衡就建连失败,排查半天才定位到转发层没开 Upgrade。
踩坑提示
假超时是最坑的:应用以为自己每三十秒发了心跳,但网关实际六十秒才超时,而中间 NAT 是九十字表项老化——三条规则不一致时,总有某一层先到点把连接静默杀掉。解法是把全链路超时列成一张表对齐,并靠心跳把最紧的那一层喂住。
再一个坑是切后台重连——桌面和移动端锁屏时 JS 定时器被挂起,心跳停了但前端没感知,等用户切回来界面还卡着旧画面。必须在 visibilitychange 回前台时主动重连,并拉一次断线期间的增量补齐。
小结
白板选机器看内存、看连接数;开长连接要喂住全链路超时、开 WebSocket 升级、对齐会话保持。规格不是越大越好,而是让「空闲连接不被任何中间层误杀」。把这三件事做齐,长连接才真的「连得稳」。别忘隐性成本:会话共享存储与快照对象存储都是慢变量,上线前就该预算到位。
延伸阅读
- 连接管理与心跳保活,见下一节 2.1。
- 断线重连与防抖,见下一节 2.4。
- 长连接服务落地,见 Node.js 云开发实战。
- 服务治理与会话粘滞,见 Go 微服务实战。
