基于YANG的可编程网络:用YANG、NETCONF、RESTCONF和gNMI实现网络自动化架构
上QQ阅读APP看书,第一时间看更新

2.7 编码(协议绑定和序列化)

YANG加上模型可以与英语等语言进行比较,语言由已知单词词典和描述单词如何组合的语法定义,交流之前仍然需要为语言编制一个编码。英语有两种非常常用的编码:文本和语音。文本编码可以进一步分为计算机编码,如ASCII、Windows-1252和UTF-8。文本也可以编码为照片文件中不同颜色的像素,如纸张上的墨水、缩微胶片或石头或铜板上的凹槽。

类似地,与基于YANG的模型相关的消息也有几种不同的编码方式(称为协议绑定或序列化),每种编码或多或少都适合于上下文。与YANG相关的最常提及(和使用的)编码是XML、JavaScript对象表示法(JSON;有两种变体)和protobuf。随着时间的推移,出现了新的编码方式。例如,本节还将介绍简明的二进制对象表示(CBOR)。

本章前面的图2-4显示了特定协议可能用不同的编码方式。请记住,有更多的编码随时可用:这是有意义的,归根结底,一个编码只是…一种编码方式。

2.7.1 XML

如果询问大多数IT专业人员是否知道XML,回答总是“是”。大多数IT人员都知道XML代表可扩展标记语言。但是,如果要求这些IT专业人员概述XML中的可扩展性机制,只有一小部分会给你合理的答复。这就是为什么第3章要简要介绍最重要的XML功能,包括可扩展性机制。

大多数人认为XML是类似HTML的文本文档,其中充满了尖括号(<some> XML</some>),这似乎是一个相当小而简单的概念。但事实并非如此,XML及其相关标准家族是一条非常复杂深邃的巨龙。它的可扩展性机制设计良好,允许基于XML的内容随着时间的推移而很好地演进,这里仅列举几个特性:它有一个名为XPath的查询语言、有一个名为XML Schema的模式语言、还有一个名为XSLT的转换语言。请记住,模式是数据结构和内容(名称、类型、范围和默认值)的定义。

由于这些特性和丰富可用的工具,NETCONF工作组决定将其协议基于XML进行消息编码。最初在YANG被发明之前,很多人假设NETCONF将使用XML Schema描述(XSD)建模。它甚至与一组附加的映射约定一起被用作大约半年的官方建模语言。当时该小组正试图为NETCONF设计第一个标准模型。然后在NETCONF权威制作的早期模型中发现了一个严重的缺陷。这引发了一场相当激烈的争论,争论的焦点是这样一个重大缺陷是如何引入的,甚至连NETCONF内部的权威人士都没有发现。其根本原因最终被声明为XML模式的难读性,促使来自整个行业不同组织的小团队聚集在一起定义一种新的模式语言,基本要求是模型必须易于读写。团队成员姓名见RFC 6020。今天,这种语言被称为YANG。

这就解释了为什么NETCONF和XML之间联系非常紧密,甚至解释了为什么YANG 1.0在很大程度上依赖于XML机制。如今,随着编码方式的不同,YANG 1.1被设计成对协议编码更加中立。

2.7.2 JSON

随着对类似于NETCONF中标准化功能的REST方法的要求不断提高,NETCONF工作组开始开发RESTCONF[21]。基于REST的传输使用广泛的消息编码,但毫无疑问,最受欢迎的是JavaScript对象表示法(JSON)。根源在于JavaScript中表示对象的方式:它是一个非常简单的编码规则集合,适合于单个页面。这种简单化是JSON受欢迎程度的主要驱动因素。如今RFC 7159中的JSON有一个清晰、精确且语言独立的定义,并在RFC 8259中进一步更新。

虽然简单性总是受欢迎的,但缺点是JSON以其简单的形式处理了许多用例,效果相当糟糕。例如,没有用于演进和扩展的机制,也没有与YANG命名空间机制相对应的机制。

另一个例子是,在典型的实现中,JSON有一个整数精度约为53位的单一数字类型。因此,YANG中的64位整数必须编码为数字(字符串)以外的其他形式。为了处理这些和其他类似但不太明显的映射情况,需要在JSON本身使用一组编码约定(如前面提到的XSD for XML)。YANG-to-RESTCONF映射见“用YANG建模的数据的JSON编码”(RFC 7951;不要与前面提到的RFC 7159混淆,尽管编号相似)。通用JSON社区也在围绕JSON的其他用例进行标准化工作,现在JSON在多功能性和复杂性方面正在接近XML。

除了JSON,RESTCONF规范(RFC 8040)还定义了如何将数据编码为XML。一些RESTCONF服务器支持JSON和部分XML,许多服务器同时支持这两种。编码是JSON它实际上是指RFC 7159中指定的JSON,加上RFC 7951中的所有约定。

2.7.3 Google protobuf

protocol buffer,简称protobuf,是gNMI中支持的另一种编码。protobuf最初是由Google发明的,广泛应用于Google的许多产品和服务中,这些产品和服务需要通过传输线路进行通信或需要的数据存储。

通过在.proto文件中定义协议缓冲区消息类型可以指定序列化信息的结构。一旦定义了消息就可以在.proto文件上运行应用程序语言的协议缓冲区编译器,以生成数据访问类。protobuf内置了对版本控制和可扩展性的支持,许多人认为这是针对JSON的优势。消息传递机制公开提供了一长串语言的绑定,使用非常广泛。

protobuf有两种格式:自描述和紧凑。就传输线路上的比特数而言,自描述模式比紧凑模式要大三倍。紧凑模式是一种紧凑的二进制形式,其优点是节省线路和内存空间。其速度要快两倍。因此这种编码非常适合遥测,在遥测中,大量数据被高频推送到一个采集器。另一方面,如果没有.proto文件,紧凑格式很难调试或跟踪,你无法判断字段的名称、含义或完整数据类型。

2.7.4 CBOR

简明二进制对象表示(CBOR)是另一种正在探讨的编码方式,尤其适用于小型嵌入式系统,通常来自物联网(IoT)。CBOR是超高效的,它甚至压缩了标识符。CBOR与客户端的CoAP管理接口(CoMI)协议结合使用。

截至本书撰写之时,CBOR(RFC 7049)还没有在基于YANG的服务器上广泛使用,但IETF核心(受限RESTful环境)工作组正在进行讨论并编写一个名为“用YANG建模的数据的CBOR编码”的文档。