系统集成
系统集成是相对拆分而言的,当巨石型应用拆分为细粒度的微服务后,错综复杂的代码可以分解为独立的模块加以治理。然而,传统应用内部原本基于方法的调用方式可能会转变为跨进程的分布式网络调用方式,网络的不可靠性给服务模块之间的交互带来了复杂性。所以,微服务系统的集成对微服务架构能否成功落地至关重要。
微服务架构强调基于HTTP的轻量级的服务交互模式,这一章我们将这种基于请求/响应模式的交互模式与RESTful架构结合,介绍微服务“声明式API”和契约优先的开发原则。同时我们会深入讲解主流RPC架构的实现原理和RPC通信方式的优势和缺点。
微服务架构的另外一种集成模式基于消息中间件的异步交互方式。这种交互模式无疑带给了微服务更多的灵活性和自治性,但也带来了复杂性,我们需要在使用场景中做出权衡,选择适合自己的消息中间件。
服务集成交互技术
我们知道软件系统的集成主要分为服务接口集成和数据集成。数据集成一般通过ETL(全称为Extract-Transform-Load,用来描述将数据从来源端经过抽取、转换、加载至目的端的过程)方式实现数据的传递、聚合等操作。ETL、实时数据流处理是数据领域与数据处理相关的技术话题,这里不赘述,本章我们只关心应用之间的交互技术和服务之间通过接口集成的技术。
微服务通常使用分布式跨网络的交互调用。我们通过网络协议、Linux I/O模式、序列化方式三个关键要素来讲解服务集成交互技术,它们是决定服务交互效果、影响交互效率最关键的因素。
本文主要讲解网络协议
分布式系统采用跨网络的协议进行通信。
网络协议是计算机网络中为进行数据交换而建立的规则、标准或约定的集合。
无论是前端与后端之间,还是后端微服务之间,交互都会涉及网络协议。
为了使不同计算机厂家生产的计算机能够相互通信,以便在更大的范围内建立计算机网络,国际标准化组织(ISO)提出了“开放系统互联参考模型”,即 著名的 OSI/RM模型(
OpenSystemInterconnection/Reference Model),它将计算机网络体系结构的通信协议划分为七层,自下而上依次为:
● 物理层(Physics Layer)
● 数据链路层(Data Link Layer)
● 网络层(Network Layer)
● 传输层(Transport Layer)
● 会话层(Session Layer)
● 表示层(Presentation Layer)
● 应用层(Application Layer)
TCP/IP无疑是当今互联网使用最广泛的网络互联协议。TCP/IP与OSI体系一样也采用了分层结构,它们之间的分层架构映射如下表所示。
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF(TheInternet Engineering Task Force,国际互联网工程任务组)的RFC793定义。TCP旨在适应支持多网络应用的分层协议层次结构。连接到不同但互联的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。
TCP主要包括两大事务:连接管理(建立、关闭连接),以及面向字节流的数据传输及控制。
建立连接TCP是互联网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN-ACK,并最终对对方的SYN执行ACK确认。TCP三次握手如下图所示。
终止连接
建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(Half-Close)造成的。具体TCP连接终止过程如下图所示。
长短连接
短连接是指当客户端与服务端建立连接后,双方完成一次读写过程,然后关闭连接,双方不需要额外的控制手段维持连接。优点是管理简单,缺点是延时高、效率低,每次传输数据需要重新建立连接。
长连接是指当客户端与服务端建立连接后,它们之间的连接不会主动关闭,后续的读写操作都会继续使用这个连接,优点是可以连续发送多个数据包,减少资源消耗、降低延时。数据传输下面是TCP在数据传输过程中的一些主要功能特性:
● TCP把数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)限制。
● 在可靠性上,TCP为了保证报文传输的可靠性,给每个包一个序号,序号也保证了传送到接收端实体的包按序接收。然后接 收 端 实 体 对 已 成 功 收 到 的 字 节 发 回 一 个 相 应 的 确 认(ACK)。如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
● 在正确性上,TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和来保证数据的正确性与合法性。
● 在流量控制上,采用滑动窗口协议,协议中规定对于窗口内未经确认的分组需要重传机制。
微服务常用的应用协议
● HTTP(Hyper Text Transfer Protocol,超文本传输协议):
HTTP可以说是目前互联网上使用的公共语言,Web浏览器、服务器和相关的Web应用程序都是通过HTTP完成通信的。HTTP基于TCP,属于应用层的面向资源存取和修改的协议,由于具有简捷、快速的特性,适用于分布式超媒体信息系统。HTTP对API技术无关性的支持是其最大的优点,浏览器的支持及不需要中间代理都简化了协议的架构。同时HTTP对RESTful架构的天然友好的支持,使其成为开发接口和系统集成的标准。
● gRPC:由Google开发,是一款语言中立、平台中立、开源的远程过程调用协议。基于HTTP2标准设计,具有诸如双向流、流控、头部压缩、单TCP连接上的多复用请求等特性。这些特性使得其在移动设备上表现更好,更省电和节省空间。gRPC客户端应用可以像调用本地对象一样直接调用另一台机器上服务端应用的方法,使得我们能够更容易地创建分布式应用和服务。与许多RPC系统类似,gRPC也基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型);在服务端实现这个方法,并运行一个gRPC服务器来处理客户端调用;在客户端拥有一个像服务端一样的方法。
gRPC最大的优势就是语言无关性,对于微服务架构技术栈多样性的特性有非常好的支持,也是很多公司采用gRPC作为自己后端系统集成的协议标准的原因。
● AMQP:全称Advanced Message Queuing Protocol,是一个进程间传递异步消息的协议。AMQP使用长连接,是一个使用TCP提供可靠投递的应用层协议。RabbitMQ就是遵从AMQP协议开发的一个RPC远程调用框架。RabbitMQ中的交换器、交换器类型、队列、绑定、路由键等都遵循AMQP中相应的概念。可以将AMQP看作一系列结构化命令的集合,这里的命令代表一种操作,类似HTTP中的方法(GET、POST、PUT、DELETE等)。
● RSocket:是一种用于反应式应用程序的新网络协议,是第七层语言无关的应用网络协议,是一种基于Reactive Streams背压的双向、多路复用、消息的二进制协议。除了TCP,同时支持的通信协议还有UDP、WebSocket等。RSocket与HTTP的不同之处在于它定义了四种交互模型。
○ fire-and-forget:异步触发,不需要响应。
○ request/response:请求/响应,发出一个请求,获取一个响应,就像HTTP一样。
○ request/stream:请求/流式响应,一个请求对应多个或无数个流式响应。
○ channel:双向异步通信,也就是支持Channel。
选择适合你的协议
上述应用层协议是我们精心选择的微服务可能会使用的网络协议,不同的网络协议适合不同的应用场景。
● 如果你的微服务之间是“点对点”的请求/响应交互方式,可以采用基于HTTP的REST方式或者RPC方式的调用。一般来说,HTTP具备更好的通用性,RPC(如gPRC)交互的性能优势更加明显,使用何种方式作为你的微服务集成标准你需要做利弊权衡。至于使用同步I/O还是异步I/O,这个基础性的选择会不可避免地影响后续的代码实现和技术架构,下一节我们会详细讲解I/O中的同步和异步、阻塞和非阻塞的相关技术和其对服务集成的影响。
● 如果你的微服务系统属于“异步执行”,或者属于一对多的发布/订阅场景,那么可以考虑使用消息中间件作为交互平台。
服务生产者与服务消费者可以使用一个第三方消息代理平台通过事件驱动机制完成服务集成。
● 对于Reactive风格的应用,通常需要非阻塞并且与异步行为匹配。很多场景是服务端从客户端请求数据,支持单个连接上的多路复用,允许任意交互模式的双向消息流。这个时候HTTP可能已经无法满足你的需求,RSocket网络协议给微服务提供了很好的端到端的网络体验,我们将会在本文的进阶篇中进一步讲解。