首页 › tech › 僵尸上下文:核心网排障实录

僵尸上下文:核心网排障实录

概述

用户手机显示“已注册”却上不了网,换了新机型才复现;批量测试500台终端只成功375台,报错却指向“签约不允许”——这类现象诡异、日志打架、重启单组件就好的“幽灵故障”,正在成为5G SA核心网运维的新常态。本文以开源核心网Open5GS社区2026年的两个真实工单为解剖样本,完整还原从现象、误导性告警、日志证据链到根因确认的全过程:一例是gNB SCTP闪断后残留的“僵尸UE上下文”,一例是UDM订阅池被非正常下线的终端慢性“漏气”耗尽。两个案例指向同一个运维命题:SBI时代,故障点、告警点与用户感知点经常不在同一个网元上。

目录

一、故障现场:两通看似不相干的工单

2026年4月19日,Open5GS社区(GitHub约2700星的开源5G核心网项目)收到一份数据完整的工单(#4427):某专网环境,商用5G SA基站(TDD制式,n77频段),核心网为Open5GS v2.7.6运行在Ubuntu 22.04上,终端是一台插了双卡的iPhone 17 Pro Max——一张专网eSIM,一张商用SIM。

现象非常有欺骗性:基站做小区重配置(内部执行lock/unlock,SCTP关联随之断开再重建),重连后gNB重新发起NG Setup并被AMF接受,iPhone重新注册成功,AMF日志里清楚地打印着"Registration complete"。随后iPhone请求PDU会话,SMF正常创建会话、分配了IP地址。一切都对,唯独上不了网。

用户面验证更是把水搅浑:从UPF向UE的IP地址发ping是通的,但ogstun接口上抓不到任何属于该UE的报文——控制面说“会话在”,用户面说“包不来”。iPhone侧显示已附著,每约16秒发起一次重试,反复失败。最诡异的是对照组:同一小区里的iPhone 14完全没有这个问题。

七周后,9月13日,第二份工单(#4789)进来,画风完全不同。一位工程师用Open5GS 2.7.5在Kubernetes单节点上搭了一套完整核心网(AMF/SMF/UDM/UDR/AUSF/NRF/SCP/PCF/BSF全部2.7.5),用PacketRusher做批量注册压测:1台、10台、25台、50台、100台、200台UE,全部干净通过;到500台,只有375台注册成功,其余被拒。UE侧收到的拒绝原因是5GMM cause: 5GS services not allowed——5GS业务不允许。

“services not allowed”这个cause,在任何一本教材里都指向签约数据问题:该用户没开户、号段没导入、签约被限制。但这位作者核对后发现签约数据没有任何问题,而且一个现象暴露了真相:只重启UDM一个组件,其他什么都不动,同样的500台立刻500/500全部通过。

375不是当前这轮压测的容量上限,而是前几轮测试留下的“遗产”。有一个池子被之前的测试悄悄填满了。

两份工单,一个关于“单台新型手机上不了网”,一个关于“批量注册莫名被拒”,看似不相干。往深处剖开,它们是同一个病灶的两个切面。

二、案例一解剖:SCTP闪断与僵尸上下文

事件时间线

时间点 事件 关键证据
T0 基站小区重配置,内部lock/unlock SCTP关联秒级断开
T1 SCTP重建,gNB发送NG Setup Request AMF接受,NG关联重新建立
T2 iPhone重注册 AMF日志:Registration complete
T3 iPhone请求PDU会话 SMF创建会话、分配IP
T4 SMF向AMF发送N1N2消息传送 SMF日志:HTTP response error [400]
T5 会话被删除,iPhone每约16秒重试 AMF日志:No UE context / No RAN UE Context
T6 重启open5gs-amfd与open5gs-smfd UE重连即恢复

三行日志拼出的真相

这份工单最有价值的地方,是作者贴出了三行互相矛盾的日志:

[smf] ERROR: [imsi-xxxx:1] HTTP response error [400]
[amf] ERROR: No UE context [imsi-xxxx]
[amf] ERROR: No RAN UE Context : AMF_UE_NGAP_ID[64]

SMF说“我在给AMF送N1N2消息(用来把下行NAS消息透传给手机)时被回了400”;AMF说“这个IMSI我没有上下文”“这个AMF_UE_NGAP_ID(64)我没有RAN侧上下文”。一边是刚刚还打印过Registration complete的AMF,一边是宣称找不到这个UE的AMF——同一个网元,对同一个用户,前后几分钟内给出了相反的答案。

把三条日志按时间排开,结论就浮出来了:SCTP闪断时,AMF没有把相关UE上下文清理干净。旧关联下的AMF-UE上下文、RAN-UE上下文、以及关联到SMF的会话状态,有一部分成了“僵尸”——它们占着位置,却不再与任何活着的NG关联挂钩。当基站重连、手机重注册后,新注册流程建立的上下文与残留的旧状态发生了冲突:会话在SMF侧创建成功,但N1N2消息送达AMF时撞上了不完整/错位的上下文,被回以400;随后会话拆除,手机进入16秒一次的循环。

这也解释了用户面的怪象:UPF能ping通UE地址,说明IP分配和隧道转发配置在数据层面是存在的;但ogstun上没有该UE的报文,因为控制面的会话根本没能在正确的上下文上站稳——一份悬空的会话,撑不起真实的流量。

至于为什么iPhone 17 Pro Max更明显而iPhone 14没事,工单作者只记录了现象,未深究机理。合理的推测方向是新机型注册行为更激进、重注册更快,更容易踩中残留窗口,但这一点在工单中并无验证,读者自行排查同类问题时不必先入为主。标准层面,NGAP(3GPP TS 38.413,RAN3工作组负责,2017年Rel-15立项,目前Release 18版本仍在演进)本身允许并要求gNB与AMF在传输层重建后重新协商NG关联,问题在于关联重建之后,受影响的UE级上下文是否被完整回收——这属于实现层面的状态机闭环问题,各厂家具体行为以其官方文档为准。

处置与验证

作者的临时处置非常干脆:在gNB重连后重启amfd和smfd,残留状态清空,UE下一次尝试即成功。这是典型的“重启能好”故障——而重启之所以有效,恰恰反证了根因是内存中的状态残留,而非配置或签约数据。

三、案例二解剖:订阅池的慢性漏气

先看懂这个池子

Open5GS的UDM里有一个SDM订阅池:终端注册时,AMF会到UDM创建一条订阅数据变更订阅;PDU会话建立时,SMF也会创建一条。默认配置下池子大小为max.ue(1024)× 每UE上限(4)= 4096条。正常流程下,终端隐式去注册时AMF会退订,SMF也会跟着退订,池子是有进有出的。

误判与自我纠错:一次教科书级的排障迭代

这份工单的曲折之处在于,作者最初报的根因是错的,而一个月后他自己用更严格的实验推翻了它——这个纠错过程本身,比结论更值得运维人细读。

第一版报告说:每台UE消耗8条订阅、下线后永不回收、AMF全程无日志。9月23日,项目核心维护者acetcom介入,要求作者开启AMF与UDM的debug日志复现。10月1日,作者带着完整日志回来了,承认三处都错了:

真正的根因:状态机在突发流量下“断链”

修正后的完整链条是这样的(以下数字均来自作者10月1日公布的实测日志):

压测中作者用kill命令直接杀掉RAN模拟器,模拟“不干净的下线”——没有任何Deregistration Request。真实世界里,这对应着基站掉电、光缆被挖断、容器被OOMKill。此时:

  1. SCTP断开,AMF删除gNB,随后在同一瞬间为500台UE逐台发起SM上下文更新(upCnxState置为DEACTIVATED)——一个500连发的SBI突发;
  2. 第一轮杀进程,500台中156台的更新发送失败(Connection reset by peer);第二轮,143台失败;
  3. AMF接着试图向这些UE下发NAS消息,撞上gNB has already been removed,流程放弃。这批UE永远停在CM-CONNECTED:不进CM-IDLE,就永远不会启动可达定时器,也就永远不会触发隐式去注册;
  4. 隐式去注册的定时链条本是:杀进程后780秒(T3512的540秒+240秒)报"Mobile Reachable Timer Expired",再过780秒执行"Implicit De-registered",然后AMF退订、释放SM上下文,SMF跟着退订。357台UE在同一秒涌入这条链,其中22台又因同样的SBI错误失败(16台Connection reset、6台SBI事务已移除),日志定格在NG context has already been removed (nas-path.c:975);
  5. 35分钟后清点:500台中仍有165台滞留在AMF,它们的324条订阅滞留在UDM。只有重启UDM才能清空。

于是池子成了只进不出的“漏斗”:每压测一轮、每真实断链一次,就永久吃掉一批配额。500台只上375台,不是容量上限,是历史欠账。而UDM日志里反复打印的Maximum number of SDM Subscriptions [4096] reached与udm_sdm_subscription_add() failed,AMF一个字都没提;UE拿到的又是那个误导性的"5GS services not allowed"。报错的网元、沉默的网元、感知故障的用户,三方各说各话。

作者还给出了一条绕过配置:把UDM配置里的global.max.ue从默认调高(如8192),报错即消失——但这只是抬高堤坝,不解决泄漏。真正的转机来自版本对照:同一套实验原封不动跑到2.8.0上,两次杀进程500台全部干净走完,无一次SBI错误,最终仅剩6条订阅属于测试床上常驻的两台UERANSIM终端。维护者将该工单标记为“非Open5GS缺陷”归档,但作者留下的那个追问很有分量:如果在现行代码上,gNB丢失后的SM上下文更新在SBI侧失败,这个UE后续还有谁会来释放它?

四、方法论:把两个案例拧成一套排障打法

两个案例,故障形态不同,排查路径却高度同构。复盘之后可以沉淀为一套可复用的打法。

flowchart TD
    A["现象:有号没网或批量被拒"] --> B["先看UE侧NAS拒绝原因"]
    B --> C["对齐三方日志 AMF/SMF/UDM"]
    C --> D{"日志能否互相印证"}
    D -->|能| E["按告警点直接定位"]
    D -->|不能| F["控制变量:单组件重启验证"]
    F --> G["负载复现:批量压测重演"]
    G --> H["版本对照:新旧版跑同一脚本"]
    H --> I["证据链闭合后再谈修复"]

案例一中那次失败会话的完整消息链,值得每个核心网工程师在脑海里过一遍:

sequenceDiagram
    participant U as 手机
    participant G as gNB
    participant A as AMF
    participant S as SMF
    G->>A: NG Setup重连被接受
    U->>A: 重注册成功
    U->>A: 请求PDU会话
    A->>S: 创建会话分配IP
    S->>A: N1N2消息传送
    A->>S: 返回400 残留上下文冲突
    S->>S: 删除会话
    U->>U: 每16秒重试仍失败

两个案例的关键要素对照如下:

维度 案例一(#4427) 案例二(#4789)
表面现象 单台手机注册成功但无数据 500台批量注册仅375台成功
误导信号 控制面全绿、UPF可ping通UE UE报"5GS services not allowed",像签约问题
真实根因 SCTP闪断后UE上下文残留 SBI突发失败致UE滞留、订阅池只进不出
决定性线索 三行互相矛盾的ERROR日志 单独重启UDM后500/500全过
定位手段 日志时间线对齐 批量压测+逐条清点SBI请求
恢复动作 重启amfd+smfd 重启UDM、调高global.max.ue
后续 关联工单继续跟踪 2.8.0复测通过

案例二还留下了一份值得抄进运维手册的参数账本:

参数 值 含义
SDM订阅池容量 4096 默认max.ue 1024 × 每UE上限4
每UE实际订阅数 2条 AMF注册一条+SMF会话一条
T3512 540秒 周期性注册更新定时器
可达定时器触发 断链后780秒 T3512的540秒+240秒
隐式去注册 可达后再780秒 到期后AMF/SMF依次退订
UE重试周期 约16秒 案例一中iPhone的会话重试间隔

五、给核心网运维人的四条实战启示

第一,故障点、告警点、感知点三分离,是SBI时代的常态而非意外。 案例二里,UDM在拼命报错,AMF一声不吭,UE收到的却是一个指向签约数据的cause。传统TDM/七号信令时代“哪个点告警就是哪里坏”的直觉,在HTTP/2+SBI的分布式事务链条上全面失效。日常巡检必须建立“跨NF日志对齐”的习惯:同一个IMSI,把AMF、SMF、UDM(必要时加AUSF/PCF)的日志按时间戳拉通看,单点日志的“正常”毫无意义。

第二,“重启大法”要升级成“控制变量重启法”。 案例二中作者单重启UDM、其他全不动,一步就把故障域从“整个核心网容量不足”收窄到“UDM一个池子”;案例一重启amfd+smfd即愈,反证了状态残留。重启本身不丢人,丢人的是全量重启——它既破坏现场,也提供不了任何定位信息。正确的姿势是:一次只动一个组件,动前抓状态、动后验现象,把每次重启变成一次假设检验。

第三,把“杀进程”纳入例行演练。 两个案例的引爆点都不是什么罕见攻击或超大规模冲击,而是一次最普通不过的SCTP闪断——基站重配置、光缆施工、电源抖动,每天都在现网发生。区别在于:断链瞬间恰逢SBI突发,一部分跨NF事务失败,状态机就断了链。压测脚本里“优雅去注册后统计成功率”只能证明happy path,“kill -9之后等35分钟再看池子余额”才能暴露真实运行周期能否自愈。案例二作者逐条清点每SUPI的POST/DELETE请求、用callbackReference区分AMF与SMF订阅的做法,值得直接抄走。

第四,版本对照是最后的“审判”。 案例二从2.7.5到2.8.0,同一脚本、同一环境,结果从“324条订阅滞留”变成“零滞留”——一次干净的对照实验,胜过十轮猜测。这也提醒升级窗口的价值:很多“疑难杂症”的最终答案不在你的参数表里,而在下一个版本号的changelog里;反过来,割接前用真实现网流量形态(含非正常断链)做回归验证,应该成为5G核心网割接预案的标配动作,而不是可选项。

六、结语

这两份工单没有登上任何新闻头条——没有断网时长、没有用户数、没有监管通报。但它们比大多数头条故障更值得运维人精读:一个是新型终端踩中残留上下文的16秒死循环,一个是500台终端的“历史欠账”填满4096格池子;一个靠三行矛盾日志破案,一个靠单组件重启锁定。它们共同演示了5G核心网运维的残酷新现实:故障不再以“整网瘫痪”的面目出现,而是以“个别用户有号没网”“批量注册莫名被拒”的碎片形态渗出,每一条碎片背后,都是某个网元里一份没人认领的僵尸上下文。

标准协议(如TS 38.413定义的NGAP)把重建与恢复的框架画得很完整,但框架之下的每一个状态机闭环,都要靠实现去兑现,靠运维去验证。手机侧那句轻描淡写的“5GS业务不允许”,背后可能是UDM日志里刷屏的池子告警、AMF日志里一行被忽略的gNB has already been removed。把这三种日志在心里接上线,才算真正吃下了5G时代的排障饭。

参考来源

  1. 3GPP TS 38.413 — NG-RAN; NG Application Protocol (NGAP) — 3GPP官方规范页:NGAP由RAN3工作组负责,Rel-15起步,Release 18最新版本18.5.0于2025年3月进入变更控制,本文NG关联重建与UE上下文的标准背景来源
  2. Open5GS Issue #4427 — AMF/SMF stale UE context after gNB SCTP reconnection causes PDU session failure (HTTP 400) — 案例一原始工单:专网环境iPhone 17 Pro Max"注册成功无数据"的完整现象、日志与复现步骤
  3. Open5GS Issue #4789 — UDM SDM subscriptions pool fills and registrations fail as "5GS services not allowed" — 案例二原始工单:含作者初始误判、维护者介入、10月1日debug级复测的全部数据(156/143/22台失败明细、35分钟滞留清点、2.8.0对照结果)
  4. Open5GS GitHub仓库 — 开源5G核心网项目主页,本文涉及组件版本(v2.7.5/v2.7.6/v2.8.0)的载体
  5. PacketRusher压测工具(gradiant容器镜像) — 案例二作者批量注册500台UE所使用的负载生成工具,随工单公布的镜像标识为gradiant/packetrusher

本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入