描述性状态迁移(representational state transfer,REST)架构风格起源于 Roy Fielding 的博士论文。Fielding 是 HTTP 规范的主要作者之一,也是 REST 架构风格的创始人。REST 是面向资源的架构(resourceoriented architecture,ROA)的基础,在这种架构中,需要将分布式应用程序建模为资源集合,访问这些资源的客户端可以变更这些资源的状态(创建、读取、更新或删除)。
REST 的通用实现是 HTTP,通过 HTTP,可以将 RESTful Web 应用程序建模为能够通过唯一标识符访问的资源集合。应用于资源的状态变更操作会采用 HTTP 动词(GET、POST、PUT、DELETE、PATCH 等)的形式,资源的状态会以文本的格式来表述,如 JSON、XML、HTML、YAML 等。
实际上,通过 HTTP 和 JSON 将应用程序构建为 REST 架构风格已成为构建微服务的标准方法。但是,随着微服务的数量及其网络交互的激增,RESTful 服务已经无法满足现代化的需求了。下面介绍 RESTful 服务的 3 个主要局限性,这些局限性妨碍了其作为消息协议在现代微服务应用程序中的运用。
01. 基于文本的低效消息协议
从本质上来讲,RESTful 服务建立在基于文本的传输协议(如HTTP 1.x)之上,并且会使用人类可读的文本格式,如 JSON。但是,在进行服务与服务之间的通信时,通信双方都不需要这种人类可读的文本化格式,这时使用这种格式非常低效。
客户端应用程序(源)生成需要发送给服务器的二进制内容,然后需要将二进制结构转换成文本(如果使用 HTTP 1.x,就只能发送文本化消息),并通过网络以文本的形式(借助 HTTP)发送到另一台机器上,这台机器需要在服务器端(目标)解析文本并将其转换回二进制结构。其实,我们也可以很轻松地发送映射服务和消费者业务逻辑的二进制内容,采用 JSON 格式主要是因为它是“人类可读的”,相对来说易于使用。这涉及工具选择问题,而不是二进制协议问题。
02. 应用程序之间缺乏强类型接
随着越来越多的服务要通过网络进行交互,而且这些服务使用完全不同的语言来构建,缺乏明确定义和强类型的服务接口成了使用RESTful 服务的主要阻碍。RESTful 中现有的各种服务定义技术(如 OpenAPI/Swagger 等)都是事后的补救措施,并没有与底层的架构风格或消息协议紧密集成在一起。
在构建这种分散的应用程序时,会遇到很多的不兼容、运行时错误和互操作等问题。例如,在开发 RESTful 服务时,应用程序之间并不需要共享服务定义和类型定义的信息。但是,在开发 RESTful 应用程序时,我们要么通过网络查看文本格式,要么使用第三方 API定义技术(如 OpenAPI)。因此,现在非常重要的任务就是拥有现代化的强类型服务定义技术以及框架,从而为多语言技术生成核心的服务器端代码和客户端代码。
03. REST 架构风格难以强制实施
REST 架构风格有很多“好的实践”,只有遵循这些实践,才能构建出真正的 RESTful 服务。但是,由于它们并没有作为实现协议(比如 HTTP)的一部分进行强制的要求,因此在实现阶段,这些实践很难实施。事实上,大多数自称 RESTful 的服务并没有遵循基础的REST 架构风格,也就是说,这些所谓的 RESTful 服务不过是通过网络公开的 HTTP 服务。因此,开发团队必须花费大量时间来维护RESTful 服务的一致性和纯度。
鉴于进程间通信技术在构建现代云原生应用程序时所存在的这些限制,人们开始寻求更好的消息协议。