5G核心网学习平台
BSF 实践篇 #09

5GC实践篇之BSF篇第3篇:BSF服务注册更新

《5G核心网原理与实践》实践篇 · BSF 网元功能

5GC实践篇之BSF篇第3篇:BSF服务注册更新

作者:爱卫生


1 测试背景与用例简介

在前面的两篇文章中,我们分别剖析了BSF的"诞生"(服务注册)和"消失"(服务去注册)。本篇则关注BSF生命周期中另一个常见且重要的操作——服务注册更新(NF Update)

在5GC的实际运营中,BSF的配置并不是一成不变的。运营商可能因为以下原因需要修改BSF的NFProfile:

  1. 扩大服务范围:新增BSF负责的IP地址段(如扩容用户、新增DNN);
  1. 缩减服务范围:移除某些IP地址段(如网络优化、地址池回收);

  2. 服务能力变更:升级API版本、修改服务端口、增加新的服务能力;

  3. 网络拓扑调整:BSF迁移到新的IP地址或端口。

以上任何变更发生后,BSF都必须主动向NRF更新其NFProfile,确保NRF中存储的信息始终与BSF的实际配置一致。如果NFProfile未及时更新,可能导致:

  • PCF通过NRF发现到BSF时,使用了错误的IP地址或端口;

  • NRF无法将特定IP地址的查询请求正确路由到BSF(地址段信息过时);

  • 新增的DNN对应的策略绑定请求无法被正确处理。

什么是BSF服务注册更新?

BSF服务注册更新是指BSF使用HTTP PUT方法,向NRF重新发送完整的NFProfile,以替换NRF中已有的旧NFProfile。这个操作对应SBI接口 Nnrf_NFManagement_NFUpdate

注意,这里使用的是与初始注册相同的HTTP PUT方法和相同的URI格式。区别在于:

  • 注册:nfInstanceID是新的,NRF创建新记录;

  • 更新:nfInstanceID已存在,NRF覆盖旧记录。

本篇测试场景

本篇以一个典型的实际场景为例:运维人员在BSF上新增一个IPv6地址段,BSF自动向NRF发起NFProfile更新,将新的IPv6前缀范围同步到NRF中。

详细消息流程图


sequenceDiagram

    participant OPS as 运维操作

    participant BSF

    participant NRF

    Note over OPS, NRF: 运维人员在BSF上新增IPv6地址段配置

    OPS->>BSF: 修改配置: 新增IPv6前缀范围

    Note over BSF: BSF检测到配置变更

    Note over BSF: 重构NFProfile

    BSF->>NRF: PUT /nnrf-nfm/v1/nf-instances/{nfInstanceID}

    Note right of BSF: 请求体含更新后的NFProfile:

    Note right of BSF: 新增了ipv6PrefixRanges条目

    NRF-->>NRF: 根据nfInstanceID查找已有NFProfile

    NRF-->>NRF: 用新NFProfile覆盖旧记录

    NRF-->>BSF: 200 OK

    Note left of NRF: 响应体含NFRegistrationData:

    Note left of NRF: heartBeatTimer

    Note left of NRF: 更新后的NFProfile


flowchart LR

    A["运维修改BSF配置"] --> B["BSF重构NFProfile"]

    B --> C["PUT /nnrf-nfm/v1/nf-instances/nfInstanceID"]

    C --> D["NRF查找已有NFProfile"]

    D --> E["NRF用新Profile覆盖旧Profile"]

    E --> F["NRF返回200 OK"]

    F --> G["BSF更新完成"]

    style A fill:#fff3e0,stroke:#e65100,stroke-width:2px

    style G fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px


测试目的

验证NRF支持BSF发起的服务注册更新流程,确保BSF能够成功更新其在NRF中的NFProfile信息。

测试前置条件

  1. SA网络中BSF和NRF网元系统及操作维护台运行正常。

  2. BSF已在NRF中成功完成初始服务注册。

  3. 服务化接口的信令监控、抓包分析工具准备就绪。

测试步骤

  1. 在BSF上修改会话绑定的IP地址段数据配置,增加BSF服务支持的IPv6地址段。

  2. 观察BSF和NRF之间的消息交互。

  3. 在NRF上查看BSF服务更新情况(对比更新前后的NFProfile)。

测试结果验证(预期)

消息1(BSF -> NRF,PUT请求)检查项:

检查项 预期结果
PUT消息的URI {apiRoot}/nnrf-nfm/v1/nf-instances/{nfInstanceID},与实际环境一致
NFProfile内容 与修改后的配置一致(包含新增的IPv6地址段)

NFProfile详细字段检查:

属性 预期结果
nfInstanceID 与实际配置保持一致
nfType BSF
nfStatus REGISTERED
serviceInstanceID 与实际配置保持一致
serviceName nbsf_management
version 与实际配置保持一致
schema http
ipEndPoints nbsf_management的服务IP和Port
bsfInfo.ipv4AddressRanges 提供服务的IPv4地址段(不变)
bsfInfo.ipv6PrefixRanges 原有IPv6地址段 + 新增的IPv6地址段

消息2(NRF -> BSF,响应)检查项:

检查项 预期结果
statusCode 200 OK(注意:不是注册时的201 Created)
头域 包含Location
Body 包含NFRegistrationData(含heartBeatTimer和更新后的NFProfile)

2 BSF服务注册更新信令深度解析

本测试的核心场景是:BSF已注册并运行,运维人员新增一个IPv6前缀范围后,BSF自动向NRF更新其NFProfile。

(注:为保护网络安全,以下log中的网元IP、NF Instance ID等敏感信息已做严格脱敏处理)

2.1 更新前的BSF配置

在发起更新之前,我们先通过NRF查询接口查看BSF当前的NFProfile,确认更新前的IPv6前缀范围配置:

更新前的IPv6PrefixRanges查询结果:


$ curl -X GET http://10.XX.XX.XX:31380/nnrf-nfm/v1/nf-instances/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX | python -mjson.tool

# 重点关注bsfInfo中的ipv6PrefixRanges字段:

    "bsfInfo": {

        "ipv6PrefixRanges": [

            {

                "start": "2a01:172:253::0/64",

                "end":   "2a01:172:253:ffff::0/64"

            },

            {

                "start": "2a01:9:2::0/64",

                "end":   "2a01:9:2:ffff::0/64"

            },

            {

                "start": "2a01:9:3::0/64",

                "end":   "2a01:9:3:ffff::0/64"

            },

            {

                "start": "2a01:9:4::0/64",

                "end":   "2a01:9:4:ffff::0/64"

            }

        ]

    }

可以看到,更新前BSF注册了4条IPv6前缀范围。

2.2 运维修改配置,BSF发起NFProfile更新

运维人员在BSF上新增一条IPv6前缀范围:2b01:9:2::0/64 ~ 2b01:9:2:ffff::0/64。BSF检测到配置变更后,自动重构NFProfile并向NRF发起PUT更新请求。


sequenceDiagram

    participant BSF

    participant NRF

    Note over BSF, NRF: Nnrf_NFManagement_NFUpdate

    BSF->>NRF: PUT /nnrf-nfm/v1/nf-instances/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

    Note right of BSF: 请求体(更新后的NFProfile):

    Note right of BSF: nfInstanceID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

    Note right of BSF: nfType: BSF

    Note right of BSF: nfStatus: REGISTERED

    Note right of BSF: bsfInfo.ipv6PrefixRanges: 4条原有 + 1条新增

    NRF-->>NRF: 查找nfInstanceID对应的已有记录

    NRF-->>NRF: 用新NFProfile完全替换旧记录

    NRF-->>BSF: 200 OK

    Note left of NRF: 响应含NFRegistrationData

    Note left of NRF: heartBeatTimer: XX秒

    Note left of NRF: NFProfile: 更新后的完整Profile

信令抓包解析:


# 1. BSF -> NRF(发起NFProfile更新 PUT请求)

PUT /nnrf-nfm/v1/nf-instances/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX HTTP/1.1

Host: 10.XX.XX.XX:31380

Content-Type: application/json

JavaScript Object Notation: application/json

  Object

    # ===== NF基本信息 =====

    Member Key: nfInstanceID

      String value: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

      # BSF的NF实例ID,与初始注册时一致

    Member Key: nfType

      String value: "BSF"

    Member Key: nfStatus

      String value: "REGISTERED"

    Member Key: serviceInstanceID

      String value: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

    # ===== NF服务信息 =====

    Member Key: nfServices

      Array

        Object

          Member Key: serviceName

            String value: "nbsf_management"

          Member Key: scheme

            String value: "http"

          Member Key: ipEndPoints

            Array

              Object

                Member Key: ipv4Address

                  String value: "10.XX.XX.XX"

                Member Key: port

                  Number value: 8080

    # ===== BSF特有信息(已更新) =====

    Member Key: bsfInfo

      Object

        Member Key: ipv4AddressRanges

          Array

            Object

              Member Key: start

                String value: "10.XX.0.0"

              Member Key: end

                String value: "10.XX.255.255"

        Member Key: ipv6PrefixRanges

          Array

            # --- 原有4条IPv6前缀 ---

            Object

              Member Key: start

                String value: "2a01:172:253::0/64"

              Member Key: end

                String value: "2a01:172:253:ffff::0/64"

            Object

              Member Key: start

                String value: "2a01:9:2::0/64"

              Member Key: end

                String value: "2a01:9:2:ffff::0/64"

            Object

              Member Key: start

                String value: "2a01:9:3::0/64"

              Member Key: end

                String value: "2a01:9:3:ffff::0/64"

            Object

              Member Key: start

                String value: "2a01:9:4::0/64"

              Member Key: end

                String value: "2a01:9:4:ffff::0/64"

            # --- 新增第5条IPv6前缀 ---

            Object

              Member Key: start

                String value: "2b01:9:2::0/64"

                # 新增IPv6前缀起始地址

              Member Key: end

                String value: "2b01:9:2:ffff::0/64"

                # 新增IPv6前缀结束地址

关键变化点:

字段 更新前 更新后
ipv6PrefixRanges条目数 4条 5条
新增条目 2b01:9:2::0/64 ~ 2b01:9:2:ffff::0/64
ipv4AddressRanges 不变 不变
nfServices 不变 不变

协议参考:根据3GPP TS 29.510 第6.1.6.2节,NF Profile更新使用与初始注册相同的PUT方法和URI。当NRF发现URI中的nfInstanceID已存在于本地数据库时,会执行更新操作而非新建。


2.3 NRF返回更新成功响应

NRF收到BSF的PUT更新请求后,执行以下操作:

  1. 查找已有记录:根据URI中的nfInstanceID在本地数据库中查找已注册的NFProfile;

  2. 替换NFProfile:用新的NFProfile完全替换旧的NFProfile(全量更新,非增量更新);

  3. 返回响应:向BSF返回200 OK(注意:不是注册时的201 Created),携带更新后的信息。

信令抓包解析:


# 2. NRF -> BSF(更新成功响应)

HTTP/1.1 200 OK

Location: http://10.XX.XX.XX:31380/nnrf-nfm/v1/nf-instances/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

Content-Type: application/json

JavaScript Object Notation: application/json

  Object

    Member Key: heartBeatTimer

      Number value: XX

      # 心跳定时器时长(秒)

    Member Key: nfProfile

      Object

        # 返回更新后的完整NFProfile

        Member Key: nfInstanceID

          String value: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

        Member Key: nfType

          String value: "BSF"

        Member Key: nfStatus

          String value: "REGISTERED"

        # ... 包含更新后的bsfInfo(5条IPv6前缀)

注册 vs 更新的响应码对比:

操作 HTTP状态码 含义
首次注册 201 Created 资源被创建
更新注册 200 OK 资源被更新

协议参考:根据3GPP TS 29.510 第6.1.6.2节,NRF在执行NF Profile更新成功后返回200 OK,响应体包含NFRegistrationDataheartBeatTimer字段可能会与初始注册时不同——NRF有权在每次更新时调整心跳周期。


2.4 【实战验证】更新后的BSF配置确认

更新成功后,我们再次通过NRF查询接口验证BSF的NFProfile是否已正确更新。

更新后的IPv6PrefixRanges查询结果:


$ curl -X GET http://10.XX.XX.XX:31380/nnrf-nfm/v1/nf-instances/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX | python -mjson.tool

# 重点关注bsfInfo中的ipv6PrefixRanges字段:

    "bsfInfo": {

        "ipv6PrefixRanges": [

            {

                "start": "2a01:172:253::0/64",

                "end":   "2a01:172:253:ffff::0/64"

            },

            {

                "start": "2a01:9:2::0/64",

                "end":   "2a01:9:2:ffff::0/64"

            },

            {

                "start": "2a01:9:3::0/64",

                "end":   "2a01:9:3:ffff::0/64"

            },

            {

                "start": "2a01:9:4::0/64",

                "end":   "2a01:9:4:ffff::0/64"

            },

            {

                "start": "2b01:9:2::0/64",

                "end":   "2b01:9:2:ffff::0/64"

            }

        ]

    }

可以看到,更新后BSF的ipv6PrefixRanges已从4条增加到5条,新增的第5条2b01:9:2::0/64已成功注册到NRF中。

更新前后对比:


flowchart TD

    subgraph 更新前

        A1["ipv6PrefixRanges: 4条"]

        A2["2a01:172:253::0/64"]

        A3["2a01:9:2::0/64"]

        A4["2a01:9:3::0/64"]

        A5["2a01:9:4::0/64"]

    end

    subgraph 更新后

        B1["ipv6PrefixRanges: 5条"]

        B2["2a01:172:253::0/64 - 不变"]

        B3["2a01:9:2::0/64 - 不变"]

        B4["2a01:9:3::0/64 - 不变"]

        B5["2a01:9:4::0/64 - 不变"]

        B6["2b01:9:2::0/64 - 新增"]

    end

    style B6 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px


2.5 【深度分析】全量更新 vs 增量更新

在3GPP TS 29.510规范中,NF Profile更新有两种实现方式:

方式 HTTP方法 说明
全量更新(Full Update) PUT 发送完整NFProfile,NRF完全替换旧记录
增量更新(Partial Update) PATCH 仅发送需要修改的字段,NRF合并更新

本测试中,BSF使用的是PUT全量更新方式——每次更新都发送完整的NFProfile,NRF用新Profile完全覆盖旧Profile。这种方式的优缺点:

全量更新(PUT)的优点:

  • 实现简单,不需要复杂的字段级合并逻辑;

  • 不会出现"旧字段残留"的问题;

  • 天然幂等——多次发送相同请求结果一致。

全量更新(PUT)的缺点:

  • 消息体较大,即使只修改一个字段也需要发送完整NFProfile;

  • 网络带宽消耗较高,尤其当NFProfile包含大量地址段时。

增量更新(PATCH)的应用场景:

心跳检测就是使用PATCH方法进行增量更新的典型场景(将在第5篇详细讨论)。PATCH方法只修改特定字段(如nfStatus),不影响其他字段。

协议参考:根据3GPP TS 29.510 第6.1.6.2节,PUT方法用于NF Profile的全量更新(Full Update),NRF应使用新收到的NFProfile完全替换已有记录。PATCH方法用于部分更新(Partial Update),仅修改指定字段。


2.6 【工程细节】更新流程中的注意事项

1) 更新期间的服务可用性

在BSF向NRF发送PUT更新请求的短暂时间内(通常几十毫秒),NRF中的NFProfile处于"旧版即将被新版替换"的过渡状态。在此期间,如果有其他NF通过NRF发现该BSF,可能看到的是旧版NFProfile。但在实际网络中,这个时间窗口极短,通常不会造成问题。

2) 更新不影响已有会话

BSF更新NFProfile(如新增IPv6地址段)不会影响已经建立的AF-PCF绑定关系。已有的绑定信息存储在BSF内部,与NRF中的NFProfile无关。NFProfile的作用仅是让其他NF能够发现和找到BSF。

3) 地址段重叠问题

新增的IPv6地址段不能与已有地址段重叠,否则NRF在进行服务发现匹配时可能返回多个BSF实例,导致结果不确定。运营商在配置新增地址段时需要仔细规划,避免地址段冲突。


正确的地址段配置:

  BSF-1: 2a01:9:2::0/64 ~ 2a01:9:2:ffff::0/64

  BSF-2: 2a01:9:5::0/64 ~ 2a01:9:5:ffff::0/64

  → 无重叠,NRF匹配结果唯一

错误的地址段配置:

  BSF-1: 2a01:9:2::0/64 ~ 2a01:9:2:ffff::0/64

  BSF-2: 2a01:9:2:8000::0/64 ~ 2a01:9:2:ffff::0/64

  → 有重叠,NRF可能返回两个BSF

4) 更新触发时机

BSF的NFProfile更新通常由以下事件触发:

触发事件 更新内容
运维修改IP地址段配置 bsfInfo.ipv4AddressRanges/ipv6PrefixRanges
运维修改DNN配置 bsfInfo.dnnList
BSF API版本升级 nfServices.versions
BSF IP/端口迁移 nfServices.ipEndPoints
负载均衡策略调整 loadLevelAvg等负载信息

3 测试结论

验证项 结果 说明
BSF服务注册更新成功 OK NRF成功更新BSF的NFProfile
PUT消息URI正确 OK 格式为/nnrf-nfm/v1/nf-instances/{nfInstanceID}
NFProfile内容正确 OK 包含原有4条+新增1条IPv6前缀
NRF返回200 OK OK 更新成功(区别于注册时的201 Created)
更新前后对比验证 OK ipv6PrefixRanges从4条增加到5条

本测试用例完美通过。BSF在运维人员新增IPv6前缀范围后,通过Nnrf_NFManagement_NFUpdate服务(HTTP PUT)成功向NRF更新了自身的NFProfile。NRF返回200 OK确认更新成功。通过更新前后的NRF查询对比,确认新增的IPv6前缀2b01:9:2::0/64已成功注册到NRF中,且原有配置信息未被破坏。整个更新流程与3GPP TS 29.510和TS 29.551规范完全吻合。

协议参考汇总

  • 3GPP TS 29.510 第6.1.6.2节:NF Profile Update流程

  • 3GPP TS 29.551:BSF Service-Based Interface,bsfInfo数据结构



关于作者:爱卫生,从事通信教学18年,出版过《5G核心网原理与实践》等4本专业书籍。学5G核心网、IMS,来51学通信就对了!知识星球:200+小时视频、3000+精华文章、1年答疑群。公众号/知识星球:51学通信,微信:gprshome201101

← 返回 BSF 实践篇