借助RPC(Remote Procedure Communication),客户端能够像调用本地方法那样远程调用某个方法的功能。早期一些很流行的RPC实现,比如通用对象请求代理体系结构(common object request broke architecture, CORBA)和Java远程方法调用(remote method invocation,RMI),他们都用来构建和连接服务或应用程序。
但是,大多数传统RPC的实现极其复杂,因为它们构建在TCP这样的通信协议之上,而这会妨碍互操作性,并且他们还有大量的规范限制,于是有了SOAP。
简单对象访问协议(simple object access protocol, SOAP)是面向服务的架构(service-oriented architecture,SOA)的标准通信技术。用于在服务之间交换XML结构化数据,并且能够基于任意的底层通信协议进行通信,其中最常用的协议就是HTTP。
但是,消息格式复杂,规范复杂,妨碍分布式应用程序的敏捷性,于是有了REST架构风格。
描述性状态迁移(representational state transfer,REST)架构风格起源于Roy Fielding的博士论文。Fielding是HTTP规范的主要作者之一,也是REST架构风格的创始人。REST是面向资源的架构(resource-oriented architecture,ROA)的基础,在这种架构中,需要将分布式应用程序建模为资源集合,访问这些资源的客户端可以变更这些资源的状态(创建、读取、更新或删除)。亦即:通过HTTP,将RESTful Web应用程序建模为能够通过唯一标识符访问的资源集合。应用于资源的状态变更 操作会采用HTTP动词(GET、POST、PUT、DELETE、PATCH等)的形式,资源的状态会以文本的格式来表述,如JSON、XML、HTML、YAML等。实际上,通过HTTP和JSON将应用程序构建为REST架构风格已成为构建微服务的标准方法。
但是,随着微服务的数量及其网络交互的激增,RESTful服务已经无法满足现代化的需求了。
基于文本的低效消息协议
RESTful服务建立在基于文本的传输协议(HTTP 1.x)上,并且会使用人类可读的格式,如JSON。但是服务与服务之间通信并不需要可读,这种格式很低效。其实可以用二进制内容来代替,采用JSON格式主要是他“人类可读”。这涉及工具选择问题,而不是二进制协议问题。
应用程序之间缺乏强类型接口
对于服务使用完全不同的语言来构建,缺乏明确定义和强类型的服务接口成了RESTful服务的主要障碍RESTful中现有的各种服务定义技术(如OpenAPI/Swagger等)都是事后的补救措施,并没有与底层的架构风格或消息协议紧密集成在一起。
在构建这种分散的应用程序时,会遇到很多不兼容、运行时错误和互操作等问题。【REST风格结构不共享服务定义和类型定义,但在开发RESTful应用程序时就需要通过网络查看文本格式或者使用第三方API定义技术(如OpenAPI)】因此,现在非常重要的任务就是拥有现代化的强类型服务定义技术以及框架,从而为多语言技术生成核心的服务器端代码和客户端代码。
REST架构风格难以强制实施
REST架构风格有很多“好的实践”,只有遵行这些实践才能构建出真正的RESTful服务。但是他们并没有作为实现协议(如HTTP)的一部分进行强制的要求。因此在实现阶段,这些实践很难实施。事实上大多数自称RESTful的服务并没有遵循基础的REST架构风格,也就是说, 这些所谓的RESTful服务不过是通过网络公开的HTTP服务 。开发团队必须花费大量时间来维护RESTful服务的一致性和纯度。
鉴于进程间通信技术在构建现代云原生应用程序时所存在的这些限制,人们开始寻求更好的消息协议。
长期以来,谷歌有一个名为Stubby的通用RPC框架,用来连接成千上万的微服务,这些微服务跨多个数据中心并且使用完全不同的技术来构建。Stubby的核心PRC层每秒能处理数百亿次的互联网请求。Stubby有许多很棒的特性,但无法标准化为业界通用的框架,因为它与谷歌内部的基础设施耦合得过于紧密。
2015年谷歌发布了开源PRC框架gRPC,这个RPC基础设施具有标准化、可通用和跨平台得特点,旨在提供类似Stubby的可扩展性、性能和功能,但它主要面向社区。
在此之后,gRPC的受欢迎程度陡增,很多大型公司大规模采用了gRPC,如Netflix、Square、Lyft、Docker、CoreOS和思科。解这gRPC加入了云原生计算基金会(Cloud Native Computing Foundation, CNCF),这是最受欢迎的开源软件基金会之一,他致力于让云原生计算具备通用性和可持续性。
Apache Thrift是与gRPC类似的RPC框架,最初由Facebook开发,后来被捐赠给了Apache。他有自己的接口定义语言并提供了对多种编程语言的支持。Thrift可以在定义文件中定义数据类型和服务接口。Thrift编译器以服务定义作为输入,能够生成客户端代码和服务器端代码。Thrift的传输层为网络I/O提供了抽象,并将Thrift从系统的其他组成部分中解耦出来,这意味着Thrift可以在任意传输实现上运行,如TCP、HTTP等。
GraphQL是另一项越来越流行的进程间通信技术,该项目由Facebook发起并通过开源进行了标准化。它是一门针对API的查询语言,并且是基于既有数据满足这些查询的运行时。GraphQL为传统的客户端-服务器端通信提供了一种完全不同的方法,该方法允许客户端定义希望获得的数据、获取方式、数据格式。
GraphQL更适合面向外部的服务或API,直接暴露给消费者。在这种情况下,消费者需要对来自服务器端的数据有更多的控制权。允许消费者使用GrapheQL查询语言来查询服务并获取想要的信息。