游戏网络基础
Category
networking / 网络基础。节点定位:把同一台服务器上同时跑着的多种流量拆成不同语义来看——本树其余节点的总纲。
Definition
游戏网络真正难的地方,不是“网络会抖”这个常识,而是系统里同时存在多种完全不同语义的流量。登录、匹配、局内输入、聊天、结算确认、活动通知、支付结果、资源下载虽然都经过网络,但它们要求的时延、顺序、可靠性和失败恢复方式完全不同。只要团队一开始不把这些语义拆开,后面就很容易出现“聊天拖慢战斗”“下载链路影响广播”“重连后会话错位”这类问题。
为什么游戏网络不能照抄普通业务系统
很多普通业务系统把一次请求视为独立事务:发请求、等结果、失败就重试。游戏系统则经常同时具备下面几种情况:
- 长连接上的持续交互。
- 对局期间的高频输入和广播。
- 局外的通知、社交和外围推送。
- HTTP 或下载链路上的资源、配置和大包数据。
所以游戏网络不是一条“统一请求通道”,而是一组语义不同、代价不同的链路并存。它的设计重点不是统一处理,而是把不同语义放进合适的路径。
Problem
先把三件事分开:连接、会话、消息
很多网络设计讨论之所以混乱,是因为“连接断了”“会话没了”“消息没到”常被当成同一类问题。更稳妥的分层是:
- 连接:TCP、UDP、WebSocket 或其他载体上的物理或逻辑通道。
- 会话:玩家当前和哪条业务上下文绑定,例如登录态、房间态、世界态。
- 消息:在连接和会话中流动的最小业务单位,例如输入、广播、通知、回包。
它们必须拆开的原因在于生命周期不同:
- 连接可能断开,但会话未必失效。
- 会话可能迁移,但连接未必要重建。
- 某条消息失败,不一定意味着整条会话失败。
重连、踢线、路由、会话恢复这些问题,本质上都是在处理三者不同生命周期之间的映射关系。
先按消息语义分层,比先谈协议更重要
从工程实践看,游戏网络最先该做的事不是拍板 TCP 还是 UDP,而是先把消息语义分开。常见至少有下面几类:
- 强控制消息:登录、鉴权、进房、结算确认、关键资产变更。
- 强实时消息:位移输入、技能输入、朝向、开火、局内高频状态变化。
- 弱实时消息:准备状态、部分位置更新、频道状态、小范围同步。
- 外围通知消息:邮件、红点、公告、好友上线、活动刷新。
- 大包传输消息:热更新资源、配置、战报、回放文件。
这些消息在优先级、可靠性、可丢弃性和重试语义上完全不同。游戏网络设计的第一原则,就是不要试图用一种处理方式覆盖所有消息。
接入层真正承担什么
接入层在简单系统里可以很薄,在高频长连接系统里却不能只是“收包转发壳”。它至少要负责:
- 连接建立、断开、心跳和超时。
- 登录态和玩家会话绑定。
- 路由到正确的房间、场景或业务节点。
- 基础限流、黑名单和异常包处理。
- 写缓冲、背压和链路质量观测。
但接入层也有明确边界:它应该理解连接和会话,不应该承载重业务逻辑。否则它一旦慢下来,整条主链路都会跟着抖。
一条更贴近真实工程的链路拆法
成熟项目通常不会追求“一种协议走天下”,而是按链路分层:
- 长连接承载登录后高频交互和推送。
- 请求响应链路承载资源、配置和外围控制请求。
- 强实时消息按更严格的时延和优先级处理。
- 强可靠消息按确认、幂等和补偿链路处理。
这种拆法的重点不是技术多样,而是承认不同消息失败后代价不同。你不应该让聊天消息的积压拖慢局内输入,也不应该让大包下载卡住房间广播。
为什么移动网络会把问题放大
在真实移动网络环境里,很多实验室里不明显的问题都会被放大:
- Wi-Fi 和蜂窝切换频繁。
- 地铁、电梯、地下车库导致短时断流和抖动。
- 后台切前台打断连接。
- 同城不同运营商链路质量差异很大。
- 设备性能也会影响收发包节奏。
所以游戏网络设计的目标,不是幻想网络稳定,而是承认波动是常态,并提前准备:
- 心跳与超时策略。
- 快速重连。
- 会话恢复。
- 关键消息幂等。
- 重连后状态重新协商或快照对齐。
为什么网络问题经常伪装成业务 Bug
线上大量“技能没放出来”“房间错乱”“位置飘”“通知晚了很久才到”的问题,看起来像业务逻辑错了,实际上可能是:
- 会话路由错了。
- 某类消息优先级不合理。
- 写缓冲积压把高频消息拖慢了。
- 弱网下可丢消息和必达消息没有分层。
- 重连后会话恢复不完整。
这就是为什么网络层必须被视为主链路能力,而不是出问题后再去排查的底层细节。
建立一套更稳妥的网络观
比较稳妥的工程观通常包括:
- 网络不是一条统一管道,而是多种语义链路叠加。
- 先按消息语义分层,再按传输方式落地。
- 连接、会话、消息三层必须严格区分。
- 主链路消息和外围消息要隔离优先级与失败语义。
- 弱网、切网、重连和异常包处理应按常态设计。
常见误区
- 把“游戏网络”理解成“都走 socket 就行”,忽视路由、压缩、限流、兼容和异常包处理。
- 把所有消息做成同一优先级、同一重试策略,结果主链路被外围流量拖慢。
- 只在稳定网络下观察系统,不把切网、重连和后台切前台当日常流量来设计。
游戏网络基础最重要的,不是先选一种“最佳协议”,而是先把主链路消息、外围链路、连接映射和恢复语义说清楚。
实战案例:一次「技能偶尔放不出来」的主链路被外围流量拖慢排查
案例为教学示例(非摘自真实项目),数字经过取整简化。它把本页「先把三件事分开:连接、会话、消息」「先按消息语义分层,比先谈协议更重要」「为什么网络问题经常伪装成业务 Bug」用到深水区:业务指标全绿、玩家体感在崩——这是晚高峰主链路被外围流量拖慢的排查,也是「怎样让不同语义的消息各走各的链路」的完整展开。
背景与现象:某 MMO 手游,日活 15 万、日对局 40 万场。上线三周后客服开始收到「技能偶尔放不出来」「位置偶尔飘」的工单,稳定在日 900 单,而同期命中率、胜率、对局时长等业务指标全部正常——正是本页说的「看起来像业务逻辑错了」。工单集中在晚高峰 20:00–22:00,低峰几乎为零。
第一步:现象与口径——先把「偶发」变成可统计的晚高峰差
客户端埋点口径:技能指令在客户端 100% 发出,发送时间戳齐全——问题不在客户端逻辑。
链路时延口径:服务端收包时间戳减客户端发送时间戳,P99 从低峰的 45 毫秒涨到高峰的 260 毫秒;同一段代码低峰压测 3 轮都是 45 毫秒。
三件事口径:高峰时段连接没断、会话没掉,只有消息晚到——连接、会话、消息拆开看,病在消息这一层。
第二步:分层归因——按本页消息语义五类逐类排查
技能指令晚到 260ms 归因
外围通知与局内输入同队列同优先级 62% → 161ms
晚高峰活动刷新把接入层写缓冲顶满 27% → 70ms
热更资源大包与局内广播共用一条 TCP 连接 11% → 29ms排查路径:先查业务逻辑(命中率正常,排除);再查会话路由(房间绑定没变,排除);最后查接入层队列——队列里局内输入、聊天、走马灯、活动刷新、热更下载混在同一优先级同一队列,晚高峰活动刷新一开,队列积压峰值 1.2 万条,排在后面的局内输入一起被拖慢。
第三步:根因——所有消息同一优先级、同一重试策略
接入层只是「收包转发壳」,没有按消息语义分层:强实时消息和外围通知消息挤在同一队列,谁先到谁先处理,外围消息的积压直接转嫁成局内输入的排队时延。大包下载走同一条 TCP 连接,进一步挤占缓冲。这正是本页说的「你不应该让聊天消息的积压拖慢局内输入,也不应该让大包下载卡住房间广播」。
第四步:处置与回填——三处改动,链路按语义拆开
- 链路拆分:局内强实时消息走独立高频通道,外围通知消息进降级队列,热更资源与大包走 HTTP 独立链路,不再与局内广播共用连接。
- 接入层加消息语义标签与优先级队列:强控制、强实时、弱实时、外围通知、大包传输五类分别排队,高优先级队列满时外围消息直接丢弃而不是堆积。
- 关键消息幂等 + 重连后快照对齐:技能输入带序列号,重连后服务端下发房间快照,客户端以快照为准重新对齐,不再逐条补发。
复核账:技能指令 P99 时延 260 毫秒 → 52 毫秒;客服工单日 900 单 → 60 单;接入层队列积压峰值 1.2 万条 → 800 条。
回填清单:
| 回填项 | 动作 | 回填处 |
|---|---|---|
| 消息语义五类标注 | 协议评审时给每类消息标注优先级、可靠性、可丢弃性,写进评审模板 | 先按消息语义分层,比先谈协议更重要 |
| 接入层优先级队列 | 接入层按语义标签分队列,高优先级满时外围消息直接丢弃 | 接入层真正承担什么 |
| 大包独立链路 | 热更资源、配置、战报走 HTTP 链路,与局内广播物理隔离 | 一条更贴近真实工程的链路拆法 |
| 重连快照对齐 | 重连后服务端下发房间快照,客户端以快照为准重新对齐 | 为什么移动网络会把问题放大 |
案例的三个教训
- 网络问题伪装成业务 Bug 时,先拆连接、会话、消息三件事,再谈业务逻辑。本案命中率全绿而工单爬坡,三件事一拆就发现病在消息晚到,不在业务代码。
- 主链路消息和外围消息必须隔离优先级与失败语义。同一队列同一策略,外围积压就会转嫁成主链路时延——分层不是优化项,是主链路能不能活的前提。
- 弱网与高峰按常态设计,不按实验室环境验收。低峰压测 3 轮全绿,高峰第 1 天就崩——验收口径要按晚高峰的流量结构来搭。
Used By
所有带服务端的玩法都要用:登录会话、房间同步、结算确认、聊天、支付回调各自挂在不同语义的链路上。验收方法:拿本页三件事(连接、会话、消息)去对任何一条链路,说不清就是设计欠账。
Related
上游:游戏类型与问题模型(industry 树,决定哪些语义必须存在)。下游:I/O 模型(02)、传输层选择(03)、协议契约(04)、消息模式(05)、可靠性顺序(06)、弱网房间广播(07)。关系链:玩法语义 → 消息语义 → 传输选择 → 协议契约 → 弱网治理。
Reference
本页为工程经验归纳,无单一外部出处;协议语义延伸见本树 02–07 各节点与教程第 04 讲《通信协议设计》;页内实战案例为教学示例(数字取整简化)。