游戏卡顿白皮书 › 按症状查找
连不上/无限加载:45 个原因及负责方
又称:登录不上、一直在加载
在含图示的完整版症状词典中打开 →
进不了游戏,或者停在加载、进场界面。
反复提示“无法连接服务器”;选完角色后进度条一直走不完。
接收新连接的环节(服务器的连接队列、防火墙、登录服务器、DB)满了。维护刚结束时尤其多见。
导致此症状的原因
L2 客户端操作系统与设备
- 安全软件检查数据包: 杀毒软件、防火墙逐个检查数据包会增加延迟,检查过度时还会把游戏误判为攻击并拦截。 (外部·外部)
L3 家庭网络
L4 公网链路
- 国家/运营商级 UDP 限制与包检测: 有些网络会封锁特定的 UDP 地址和端口,或限制 UDP 速率;包检测设备还会过滤掉它识别不了的协议。用 UDP 通信的游戏在这类网络里会连不上,或频繁掉线。 (外部·外部)
- DNS 故障/延迟: DNS 负责把服务器域名解析成地址。DNS 慢或失败时,就找不到登录服务器和更新服务器。 (外部·外部)
- DDoS 导致共享线路饱和: 针对游戏公司或同一网络中其他目标的大流量攻击,会把共享线路占满。 (运维团队·网络运维)
- 运营商共享 IP(CGNAT): 移动网络和部分运营商让多个用户共用一个 IP,并会在很短时间内清掉空闲连接的映射。 (研发团队·客户端开发)
- 经由 VPN/游戏加速器: 开启 VPN 或游戏加速器后,数据包会经过该公司的中转服务器。中转服务器远或拥挤时,反而会变慢。 (外部·外部)
L5 数据中心网络设备
- 防火墙会话表耗尽: 防火墙会把放行的每个连接记到会话表里加以跟踪。表满之后就无法接受新连接。 (运维团队·网络运维)
- DDoS 防护引流/误判: 为防御攻击把流量牵引到清洗中心后,路径会变长,还可能把正常用户误判为攻击而拦截。 (运维团队·网络运维)
- 云 NAT 网关连接/端口上限: 私有子网中的服务器访问外部(平台认证、支付、外部 API)时,由 NAT 网关替换地址和端口后发出。发往同一目的地的并发连接超过网关的端口上限,新连接就会失败。 (运维团队·网络运维)
- 负载均衡倾斜/健康检查误判: 连接全都挤到一台服务器上,或者一直把玩家分配到已经挂掉的服务器。 (运维团队·网络运维)
- MTU 不匹配(只有大包丢失): 中间某段的 MTU(一次能发送的最大尺寸)变小,而包过大通知又被拦截时,只有大包会一直丢失。 (运维团队·网络运维)
L7 服务器操作系统(内核)
- 连接队列(backlog)溢出: 维护结束后数万人同时连接时,内核的连接队列(backlog)会溢出,连接请求被丢弃。 (研发团队·服务器开发)
- 文件描述符上限: 每个连接都要占用一个文件描述符(fd,操作系统给打开的文件、socket 分配的编号),而一个进程能打开的 fd 数量是有限的。 (运维团队·系统运维)
- 服务器 conntrack 表耗尽: Linux 防火墙会把所有连接记在连接跟踪(conntrack)表里,这张表达到上限后,新的数据包会被丢弃。 (运维团队·系统运维)
- 服务器间连接的临时端口耗尽: 游戏服务器频繁地与 DB 或其他服务器建立短连接又断开时,断开的连接会在一段时间内占着端口,导致新连接打不开。 (研发团队·服务器开发)
L8 Socket 与协议
- keepalive 默认 2 小时: 对方没发关闭信号就消失时,TCP 要过很久才能发现。keepalive(确认空闲连接是否还活着的 TCP 功能)默认关闭,开了也要空闲 2 小时才开始确认。 (研发团队·服务器开发)
- SO_REUSEPORT 分配不均: 多个进程分担同一个端口时,内核会按地址哈希给每个连接定好负责的进程,之后不再改变。负责的进程一旦停住,只有分到它那里的人在等。 (研发团队·服务器开发)
L9 服务器游戏进程
- 线程池耗尽: 处理任务的工作线程全被慢操作占住时,新请求只能干等。 (研发团队·服务器开发)
L11 磁盘
- 写入 core dump: 服务器崩溃时要把数 GB 内存写到磁盘,重启有时会因此推迟好几分钟。 (运维团队·系统运维)
L12 数据库
- 缺少索引的查询: 没有索引时,要找到符合条件的行,就得把整张表读一遍(全表扫描)。 (研发团队·服务器开发)
- 连接池耗尽: 与 DB 建立的连接数是固定的,慢查询占住连接后,其余请求只能等待。 (研发团队·服务器开发)
- 冷缓存(刚重启时): DB 重启后内存缓存是空的,一段时间内所有查询都要从磁盘读取。 (运维团队·数据库运维)
- 登录激增与 N+1 查询: 加载一个角色要分别查询几十次时,数万人同时登录就会变成几百万条查询。 (研发团队·服务器开发)
- DB 故障切换: 主库宕机、切换到备库期间无法写入,最后一部分没来得及复制的数据可能会丢失。 (运维团队·数据库运维)
- 缓存雪崩: 热门数据的缓存同时过期时,几千个请求会一下子涌向 DB。 (研发团队·服务器开发)
- Redis 慢命令: Redis 一次只处理一条命令,一条慢命令就会挡住后面所有请求。 (研发团队·服务器开发)
- 执行计划变化导致查询变慢: 代码没变,DB 却换了处理同一条查询的方式(执行计划),昨天 2 ms 的查询今天就变成几百 ms。 (运维团队·数据库运维)
- 线上表结构变更(DDL)锁: 在服务运行中给表加列或加索引,仅仅因为一个短暂需要的锁,使用这张表的所有请求都可能被迫等待。 (运维团队·数据库运维)
L13 服务器架构与运维
- 场景切换(服务器间迁移): 进入其他区域或副本时,要把角色数据交给另一台服务器,这个过程中会出现延迟和失败。 (研发团队·服务器开发)
- 级联故障: 一个服务变慢,调用它的服务器都会因等待响应而被占住,连不相关的功能也会停摆。 (研发团队·服务器开发)
- 辅助服务器故障: 聊天、组队、拍卖行这类与游戏服务器分开运行的服务器出故障时,只有对应的功能不能用。 (研发团队·服务器开发)
- 发布/重启: 为更新而重启服务器时,如果不迁移连接,这台服务器上的玩家都会掉线,关机前的存盘和随后的重连也会一下子挤在一起。 (研发团队·服务器开发)
- 弹性伸缩延迟: 人一多就会自动增加服务器,但准备要几分钟,这段时间现有服务器处于过载状态。 (运维团队·系统运维)
- 依赖外部服务: 平台登录、支付、实名认证这类外部服务变慢或停摆时,流程会卡在那一步。 (外部·外部)
- TLS 证书过期/配置错误: 登录、API、补丁服务器的证书过期或缺少中间证书时,从那一刻起新建连接的客户端 TLS 连接都会失败。 (运维团队·网络运维)
- 登录排队上限/重连保留不足: 上线、维护结束后连接集中涌入时,登录排队达到上限,开始拒绝新的排队;正在排队的玩家只要短暂断开一下就会丢掉位置,回到队尾。 (研发团队·服务器开发)
同步设计
只有部分人遇到的问题
- 特定角色数据过于庞大: 物品、邮件堆了几千个,或者好友列表、黑名单、buff 特别多的角色,登录、存盘、向周围广播的数据量是别人的好几倍。与线路无关,只有用这个角色时才慢。 (研发团队·服务器开发)
- 固定 UDP 端口冲突: 客户端被做成使用固定的本地端口时,同一台电脑上的第二个客户端要么用不了这个端口,要么和第一个客户端分着收包。 (研发团队·客户端开发)
- 多开限制: 安全模块或服务器策略限制一台电脑上开多个客户端时,第二个客户端会无法启动或连接,或者先开的那个掉线。有些游戏只禁用额外客户端的部分功能。 (研发团队·客户端开发)
TCP 重传的根本原因
- 防火墙/连接跟踪丢包: 防火墙或 Linux 连接跟踪(conntrack,把经过的连接记录到表里的功能)在表满了,或判断连接状态不对时,会丢弃数据包。 (运维团队·网络运维)
- MTU 黑洞(只有大包反复丢失): 中间链路能通过的包变小了,“包太大”的通知(ICMP)却被拦截,大包无论重发多少次都会丢失。 (运维团队·网络运维)
- 连接请求(SYN)重传: 连接请求因连接队列(backlog)溢出或被防火墙拦截而丢失时,客户端操作系统会从 1 秒后开始,以逐渐拉长的间隔重发。 (研发团队·服务器开发)
查看含图示的完整版症状词典