好的,我们继续对3GPP TS 29.594规范第四章的“服务操作”进行深度剖析。在上一篇中,我们已经彻底掌握了Subscribe这通关键“电话”是如何打出的。现在,是时候探索这通电话所建立的“约定”是如何被履行和终止的了。

深度解析 3GPP TS 29.594:4.2 Service Operations (Part 2 - Unsubscribe & Notify 操作)

本文技术原理深度参考了3GPP TS 29.594 V18.4.0 (2024-06) Release 18规范中,第四章“Service Operations”的核心章节,重点解读4.2.3节“Nchf_SpendingLimitControl_Unsubscribe”和4.2.4节“Nchf_SpendingLimitControl_Notify”。本文旨在为读者完整呈现消费限额控制订阅生命周期的后半环——如何优雅地“终止约定”,以及“约定”将如何被CHF忠实地“履行”,从而构建一个完整的异步通信闭环。

引言:从“约定”到“履行”与“终止”

在我们的故事中,PCF已经为用户乐乐的高清直播业务,成功地向CHF订阅了LiveStream_Data_Counter的状态变化通知。一个“信息快递”的约定已经达成。

现在,我们将见证这个约定的两种最终结局:

  1. 约定的履行 (Notify): 当乐乐沉浸在直播的快乐中,她的定向流量包被不断消耗,最终触及了CHF设定的阈值。此时,CHF这位信守承诺的“快递员”将立刻出动,将最新的“消费战报”火速送达PCF。
  2. 约定的终止 (Unsubscribe): 当乐乐心满意足地关闭直播APP,对应的PDU会话结束时,PCF这位理智的“客户”会主动打电话给CHF取消订阅,礼貌地告知“快递服务辛苦了,暂时不需要了”。

本篇文章将详细拆解Unsubscribe(退订)和Notify(通知)这两个服务操作的逻辑流程,为我们理解Nchf_SpendingLimitControl服务的完整生命周期,画上最后的点睛之笔。


1. 解读第4.2.3章 Nchf_SpendingLimitControl_Unsubscribe service operation (退订服务操作)

Unsubscribe操作是订阅生命周期的标准退出机制,确保了资源的有效管理。

3GPP TS 29.594 - 4.2.3.1 General

The Nchf_SpendingLimitControl_Unsubscribe service operation is used by the NF service consumer to cancel the subscription of status changes for all the policy counters available at the CHF. That means the complete cancellation of the spending limit reporting procedure.

这段话强调了Unsubscribe操作的彻底性:它会完全取消(complete cancellation) 整个消费限额报告流程。

1.1 Unsubscribe操作的信令流程图剖析

规范通过“Figure 4.2.3.2-1: NF service consumer unsubscribes from spending limit reporting”这张图,展示了退订的简洁交互。

如下文所述,规范原文中的“Figure 4.2.3.2-1”清晰地描绘了服务消费者(PCF)与CHF之间的退订流程。

步骤1:PCF 发起 HTTP DELETE 请求

Figure 4.2.3.2-1, Step 1: 1. DELETE.../subscriptions/{subscriptionId}

场景链接:乐乐关闭了直播APP,SMF通知PCF对应的PDU会话即将终止。PCF意识到,它不再需要监控乐乐的LiveStream_Data_Counter了。于是,PCF从其会话上下文中取出了之前保存的那个订阅ID——sub-lele-live

PCF随即构造了一个HTTP DELETE请求,其Request-URI直指CHF上代表该订阅的那个特定资源: {apiRoot}/nchf-spendinglimitcontrol/v1/subscriptions/sub-lele-live

  • HTTP方法: DELETE。这是RESTful API中用于删除资源的唯一标准方法,语义清晰,意图明确:“请将这个URI所标识的资源从你的系统中移除”。
  • 请求体: DELETE请求没有请求体。所有必要信息(即要删除哪个订阅)已经包含在URI中了。

步骤2:CHF 返回 204 No Content 响应

Figure 4.2.3.2-1, Step 2: 2. 204 No Content

CHF收到DELETE请求后,执行以下动作:

  1. 从URI中解析出subscriptionId (sub-lele-live)。
  2. 在其订阅数据库中查找并删除该订阅记录。
  3. 构造一个204 No Content的HTTP响应。
  • HTTP状态码: 204 No Content,表示“删除操作已成功执行,我没有其他信息需要返回给你”。这是DELETE操作成功的标准响应。

如果PCF提供的subscriptionId无效或已过期,CHF会返回404 Not Found等错误码,并可能在响应体中包含ProblemDetails来提供更详细的错误原因。

至此,PCF与CHF之间关于乐乐直播业务的订阅契约被干净利落地解除了。CHF将不再为这个已删除的订阅发送任何通知。


2. 解读第4.2.4章 Nchf_SpendingLimitControl_Notify service operation (通知服务操作)

Notify是整个订阅/通知模式的核心价值所在,是CHF主动履行其“报告”职责的体现。

3GPP TS 29.594 - 4.2.4.1 General

The Nchf_SpendingLimitControl_Notify service operation is used by the CHF:

  • to notify the change of the status of the subscribed policy counters…; and/or
  • to provide one or more pending statuses for a subscribed policy counter…; and/or
  • to request the termination of the subscription…

这段话概括了Notify操作的三大用途:

  1. 报告当前状态变化: 这是最主要的用途。
  2. 提供待生效状态: 报告未来某个时间点即将发生的状态变化。
  3. 请求终止订阅: 一个特殊的、由CHF发起的“反向退订”请求。

2.1 Spending limit report (消费限额报告) 流程剖析

这是Notify最经典的用法。规范通过“Figure 4.2.4.2-1: Spending limit reporting”这张图来描述。

步骤1:CHF 发起 HTTP POST 请求

Figure 4.2.4.2-1, Step 1: 1. POST.../{notifUri}/notify

场景链接:乐乐正在观看直播,她的LiveStream_Data_Counter用量达到了19GB(95%阈值)。CHF内部机制检测到这个计数器的状态从"VALID"变为"FINAL"

这个状态变化是触发器。CHF立刻行动:

  1. 查找该计数器的订阅者,找到了PCF为乐乐创建的sub-lele-live订阅。
  2. 从该订阅记录中,取出PCF当初提供的回调地址notifUri
  3. 构造一个HTTP POST请求,目标URI为 {notifUri}/notify。注意,规范建议在回调URI后附加/notify段,以明确区分不同类型的通知。

请求体 (SpendingLimitStatus) 的深度剖析: 这个POST请求的Body,与Subscribe成功时的响应体一样,是一个SpendingLimitStatus JSON对象。

  • supi (M): 必须包含乐乐的SUPI,让PCF知道这是关于哪个用户的通知。
  • notifId (C): 如果PCF在订阅时提供了,CHF必须在这里回传,帮助PCF关联上下文。
  • statusInfos (M): 包含了状态发生变化的那个计数器的最新信息。例如:
    {
      "supi": "supi-of-lele",
      "statusInfos": {
        "LiveStream_Data_Counter": {
          "policyCounterId": "LiveStream_Data_Counter",
          "currentStatus": "FINAL", // 核心信息:状态已变为FINAL
          "penPolCounterStatuses": [ // 可选:可能还预告了未来的变化
            {
              "policyCounterStatus": "EXHAUSTED",
              "activationTime": "2025-10-13T18:30:00Z"
            }
          ]
        }
      }
    }
  • expiry (O): CHF还可以利用这次通知,顺便更新一下订阅的有效期。

步骤2:PCF 返回 204 No Content 响应

Figure 4.2.4.2-1, Step 2: 2. 204 No Content

PCF的notifUri端点接收到这个POST请求后,立即返回204 No Content以确认收到。随后的策略决策更新是PCF内部的异步行为。

PCF收到"FINAL"状态后,可能会更新策略:当LiveStream_Data_Counter完全耗尽(变为"EXHAUSTED")时,立即将业务切换到Total_Data_Counter计费,并可能将QoS等级从GBR(保障比特率)降为Non-GBR(非保障比特率)。

2.2 Subscription termination request by CHF (由CHF发起的订阅终止请求)

这是Notify的一个特殊用法,规范通过“Figure 4.2.4.3-1”来描述。

场景链接:乐乐的家庭账户因为欠费被销户了。CHF内部清除了乐乐的所有计费信息。此时,PCF为乐乐建立的那个订阅已经没有意义了。

CHF会向PCF的回调URI发起一个特殊的POST请求,其URI为{notifUri}/terminate

  • 请求体 (SubscriptionTerminationInfo): 包含supitermCause(终止原因)字段,例如 termCause: "REMOVED_SUBSCRIBER"

PCF收到这个请求后,就知道了这个订阅已失效,它会清除本地相关的订阅上下文,并返回204 No Content。这是一种由服务提供者主动发起的、优雅的资源清理机制。


总结

通过对UnsubscribeNotify服务操作的深度剖析,我们已经完整地构建了Nchf_SpendingLimitControl服务异步通信的生命周期闭环。

  1. 清晰的生命周期管理: Subscribe (POST) 创建订阅,Unsubscribe (DELETE) 销毁订阅,生命周期管理清晰、标准,完全符合RESTful设计哲学。

  2. 信息丰富的通知 (Notify): Notify操作不仅能报告当前的状态变化,还能预告未来的待生效状态,极大地增强了PCF策略决策的前瞻性和智能性。通知内容SpendingLimitStatus的设计,信息量大且结构清晰。

  3. 双向的终止机制: 订阅不仅可以由消费者(PCF)通过Unsubscribe主动终止,也可以在特定情况下(如用户销户)由提供者(CHF)通过特殊的Notify请求来提议终止,这使得整个订阅管理机制更加健壮和完善。

我们已经走完了第四章“服务操作”的全部核心内容。我们不仅理解了每个操作的功能,更洞悉了它们在真实网络场景中是如何被触发和执行的。在下一篇文章中,我们将进入第五章和第六章,开始将所有这些功能逻辑,映射到具体的API资源和数据模型定义上,完成从“做什么”到“怎么实现”的最后跨越。


FAQ

Q1:Unsubscribe操作是必须的吗?如果PCF在会话结束后忘记退订会怎么样? A1:Unsubscribe是强烈推荐的最佳实践。如果PCF忘记退订,那个订阅资源会一直保留在CHF中,直到它因为expiry(过期时间)到达而自动失效。如果订阅时没有设置过期时间,它可能会成为一个“僵尸订阅”,持续占用CHF的资源。更糟糕的是,如果该用户后续还有消费状态变化,CHF仍然会向PCF(可能已经不再关心此会话)发送Notify消息,造成不必要的信令开销。

Q2:CHF在发送Notify时,如果PCF的notifUri暂时不可达,会发生什么? A2:CHF会认为这次通知投递失败。一个健壮的CHF实现应该包含重试机制。它会根据预设的策略(例如,指数退避算法)在一段时间内重试几次。如果多次重试后仍然失败,CHF可能会认为PCF已经出现故障或下线,此时CHF可能会单方面将该订阅标记为“暂停”或直接删除,以避免后续的无效投递。

Q3:Notify操作中,CHF报告状态变化时,是一有变化就立刻通知,还是会做一些聚合或延迟? A3:规范并未强制规定。这取决于运营商的策略和CHF的实现。

  • 实时模式: 对于某些对延迟敏感的业务(如实时游戏),CHF可以配置为只要状态一变化就立即通知。
  • 聚合模式: 对于变化频繁但延迟不敏感的计数器,CHF可以配置为在一定时间窗口(如1秒)内聚合多次状态变化,只通知最后一次的状态,以减少信令风暴。 这种灵活性允许运营商根据业务需求来平衡实时性和信令开销。

Q4:CHF发起的“订阅终止请求”和PCF发起的Unsubscribe有什么区别? A4:发起方动因完全不同。

  • UnsubscribePCF发起的,动因通常是PCF侧的事件,例如它所管理的PDU会话结束了,它不再需要这些信息。
  • “订阅终止请求”是CHF发起的,动因通常是CHF侧的事件,例如用户被销户,相关的计费档案已不存在,CHF无法再提供这些信息。 这是一种对称的设计,确保了订阅关系可以在任何一方发生变化时,都能被优雅地终止。

Q5:PCF能否在一个Unsubscribe请求中删除多个订阅? A5:不能。DELETE .../subscriptions/{subscriptionId}这个API的设计决定了它一次只能删除一个由subscriptionId唯一标识的订阅资源。如果PCF需要删除多个订阅,它必须为每个订阅分别发起一次DELETE请求。