使用 gNMI 订阅遥测数据
gNMI 协议定义了 Subscribe
用于订阅遥测数据的 RPC。遥测收集器使用此 RPC 从网络设备请求更新状态和配置数据。
对新订阅的请求封装在包含一个或多个资源路径的消息中SubscribeRequest
。订阅的路径与目标网络设备上的特定数据实例相关。请求可以包含基于 OpenConfig 或本机 Junos 架构的路径。
订阅请求还必须包括以下模式之一:
-
ONCE
- 一次性数据请求。 -
POLL
- 用于定期按需检索数据。 -
STREAM
- 根据指定的触发器流式传输数据的长期订阅。
模式中的 STREAM
订阅必须指定以下子模式之一:
-
ON_CHANGE
- 仅当数据项的值发生更改时,才会发送数据更新。 -
SAMPLE
- 根据订阅请求中指定的间隔期,每个采样间隔发送一次数据更新。默认采样间隔为 30 秒。 -
TARGET_DEFINED
- 接收订阅请求的网络设备基于每个叶确定数据的最佳传递类型。如果消息中指定的路径引用事件驱动的数据,ON_CHANGE
则可以创建订阅。对于表示计数器值SAMPLE
的数据,可能会创建订阅。注意:TARGET_DEFINED
配置路径的订阅请求仅被视为ON_CHANGE
请求。
对于 ONCE
和 ON_CHANGE
SAMPLE
订阅,收集器可以请求包含订阅中路径的当前状态的初始更新。此更新(也称为初始同步)很有价值,因为:
-
收集器可以完整查看设备上该传感器路径的每个字段的当前状态。
-
在看到下一个事件之前,收集器至少接收一次事件驱动的数据 (
ON_CHANGE
)。这样,收集器就可以在下一个事件发生之前知道数据状态。 -
发送包含零计数器值的数据包转发引擎传感器,这些计数器值通常由于零抑制而不会出现在流数据中。这可确保收集器知道每个线卡中的所有字段。
目标设备通过消息 SubscribeResponse
响应订阅请求。如果订阅请求要求进行初始同步,则目标将发送数据,后跟标志设置为 sync_response
true
的响应消息。初始同步后,目标设备会根据订阅模式继续更新路径。
该 SubscribeRequest
消息包含一个名为 updates_only
的标志。当此标志设置为 true
时,目标设备不会发送初始同步,只会发送后续更新,如下所示:
-
对于
STREAM
处于模式的SAMPLE
订阅,更新将在下一个采样间隔发送。 -
对于
STREAM
处于模式的ON_CHANGE
订阅,更新将在下次值更改时发送。 -
对于
ONCE
订阅,仅SubscribeResponse
发送sync_response
false
设置为 的 ,并且关闭订阅。 -
TARGET_DEFINED
订阅被视为ON_CHANGE
配置路径,更新在下次值更改时发送。
和SubscribeRequest
SubscribeResponse
消息的内容在 gnmi.proto 文件中定义。有关订阅 RPC 和订阅模式的详细信息,请参阅 gNMI 规范,网址为:gNMI 规范:订阅遥测更新。
以下限制适用于配置路径:
-
POLL
不支持订阅。 -
前缀路径不包括在更新消息中。
-
特定于瞻博网络的元数据操作(如
active/inactive
、insert before/after
、comment/annotate
和protect/unprotect
)不支持 gNMI 响应。这些可能出现在消息中,但无效。 -
include
SubscribeRequest
suppress_redundant
、heartbeat_level
、allow_aggregation
和qos
中不支持的参数。 -
仅支持原型编码。
-
不支持邮件中的
SubscribeRequest
扩展名 -
仅在密钥级别支持筛选订阅路径。
和
TARGET_DEFINED
订阅不支持ON_CHANGE
以下提交变体:commit at
、commit prepare/activate
和批处理提交。从
edit dynamic
以及edit private
编辑或配置模式。-
不会为状态容器发送更新消息。
-
对于标识符或密钥是唯一配置叶的订阅列表,可能没有更新消息。
例子
以下示例显示了 gNMI 客户端和目标设备以 protobuf 格式发出的订阅请求和响应。
示例:ONCE 模式
以下示例显示了从 gNMI 客户端以 protobuf 格式发送的订阅请求。订阅模式为 ONCE
/system/aaa/authentication/users:
root@controller:~# /usr/local/bin/gnmic sub -a 10.225.0.0:32767 --mode once --path /system/aaa/authentication/users -u <username> -p <password> --format prototext
目标使用一次性更新进行响应:
update: { timestamp: 1676294840 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test2" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } }
示例:ON_CHANGE
以下示例显示了处于子模式的STREAM
ON_CHANGE
订阅请求。OpenConfig 资源路径为 /system/aaa/authentication/users/user[username=“test1”]:
root@controller:~# /usr/local/bin/gnmic sub -a 10.225.0.0:32767 --mode stream --stream-mode on-change --path /system/aaa/authentication/users -u <username> -p <password> --format prototext
订阅请求时的 OpenConfig 配置:
user@root> show configuration openconfig-system:system aaa authentication | display set set openconfig-system:system aaa authentication users user test1 config password $ABC123 set openconfig-system:system aaa authentication users user test1 config role superuser
示例响应消息显示配置路径的值和 sync_response
设置为 的标志 true
:
update: { timestamp: 1676311979 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } } sync_response: true
对订阅路径进行了以下配置更改:
-
为 添加
test1
用户名。 -
删除 的密码
test1
。
目标设备发送以下更新作为响应:
update: { timestamp: 1676312428 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } delete: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } }
示例:示例
以下示例显示了模式和SAMPLE
子模式下的STREAM
订阅请求。OpenConfig 资源路径为 /system/aaa/authentication/users/user[username=“test1”]:
root@controller:~# /usr/local/bin/gnmic sub -a 10.225.0.0:32767 --mode stream --stream-mode sample --sample-interval 5s --path /system/aaa/authentication/users -u <username> -p <password> --format prototext
订阅请求时的 OpenConfig 配置:
user@root> show configuration openconfig-system:system aaa authentication | display set set openconfig-system:system aaa authentication users user test1 config username test1 set openconfig-system:system aaa authentication users user test1 config password "$ABC123" set openconfig-system:system aaa authentication users user test1 config role superuser
示例响应消息显示发送的初始更新(标志 sync_response
设置为 true
)和后续更新,每隔 5 秒发送一次:
update: { timestamp: 1676295454 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } } sync_response: true update: { timestamp: 1676295459 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } } update: { timestamp: 1676295464 update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "username" } } val: { string_val: "test1" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "password" } } val: { string_val: "$ABC123" } } update: { path: { elem: { name: "system" } elem: { name: "aaa" } elem: { name: "authentication" } elem: { name: "users" } elem: { name: "user" key: { key: "username" value: "test1" } } elem: { name: "config" } elem: { name: "role" } } val: { string_val: "superuser" } } }