架构杂谈《九》
架构杂谈《九》
微服务与轻量级通信机制
微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间胡亮协调、互相配合,为用户提供最终价值。在微服务架构中,服务与服务之间通信时,通常是通过轻量级的通信机制,实现彼此间的互通互联、互相协作。所谓轻量级通信机制,通常是指与语言无关、与平台无关的这类协议。通过轻量级通信机制,使服务与服务之间的协作变得简单、标准化。
1、同步通信与异步通信
1.1概述
微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务。因此,微服务架构本质上分布式系统。
相比传统的单机系统,由于服务和数据分布在不同的节点上,每次交互都需要跨节点与运行,这使得网络成为微服务架构实施考虑的必要因素之一。
1.2 同步通信与异步通信的选择
同步通信是指当客户端发出请求后,在服务端处理未结束前,客户端一直处于等待状态,直到最终获得服务端的响应。
异步通信则是指当客户端发出请求后,服务端或者第三方组件会先接受消息并应答,然后在合适的时间对请求进行处理。在这中间。客户端不需要一直处于等待状态。
2、远程调用RPC
RPC(Remote Procedure Call)又称远程过程调用。是一种典型的分布式节点间同步通信的实现方式。远程过程调用采用客户端/服务端的模式,请求的发起者是客户端,提供响应的是服务器端。
客户端通过客户代理存根(Stub),传递函数参数,向服务器端发起函数调用。服务器端通过服务器代理存根(Skeleton),接受到客户端的请求后,对请求进行处理。并在结束后向客户端返回响应,从而完成一次通信。
2.1远程过程调用的核心
远程过程调用采用客户端/服务器端模式。请求的发起者是客户端,提供响应的是服务器端。客户端与服务器端的交互模式图如下:
1、首先,客户端调用本地代理存根,发送请求到服务器端,等待应答信息
2、在服务器端,服务代理处于睡眠状态,直到客户端请求到达并将其唤醒
3、服务代理获得请求参数后,交由服务器的服务代码对其进行处理
4、应用程序处理结束后,由服务代理向客户端发送应答,等待下一次请求
5、客户端代理存根接收应答信息,交给客户端的调用代码进行处理。
2.2远程方法调用
传统的远程过程调用框架主要包括 Sun RPC、DCE/RPC,主要基于C语言实现,以函数调用为主。
随着面向对象语言的快速发展,序列化/反序列化等特性的诞生。基于不同语言的远程过程调用框架开始提供对象远程访问的功能,如 Thrift、protocol buffers等,同传统的远程过程调用框架相比,有一类框架能够允许客户端通过面向对象的调用方式,调用远端的实现。我们称这类调用为远程方法调用,换句话说 远程方法调用是远程过程调用的一种面向对象的实现。
2.3 RPC的弊端
RPC 通过 使用代理存根(Stub/Skeleton)的方式,屏蔽了通信双发底层的调用细节,让客户端不必显式地区分当前代码级别的方法调用是本地调用还是远程调用。因此使分布式节点间的通信变得简单。但是,虽然RPC 的调用机制屏蔽了调用的细节,简化了调用流程。但其也存在着弊端。
1:耦合度高
2:灵活性差
3、REST
3.1 REST 概述
REST(Representation State Transfer)(表述性状态传递)是这几年使用较广泛的分布式节点间通信的实现方式,REST 从语义层面将响应结果定义为资源,并使用HTTP的标准动词映射为对资源的操作,形成了一种以资源为核心、以HTTP为操作方式的,与语言无关、平台无关的服务间通信机制。
3.2 REST的核心
资源:(Resource)是一种抽象的概念,是指对某类信息实体的抽象。实体是指服务器端需要处理的具体信息,它可以是一段文本、一种图片也可以是文件系统中的一个文件、数据库中的一张表等。与面向对象设计中的概念类似,资源通常以名词为核心来定义,每个资源对应一个特点的URI作为标识。
表述:(Representation)资源的表述是对资源在某个特定时刻的状态的描述。资源是一种信息实体,实体在客户端与服务器端进行信息交换时,可以有多种表现形式,如:文本可以用TXT格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式标识也可以用PNG格式表现。这种资源的表述格式在客户端与服务器端通过请求-响应的协商机制来确定。实际上,URI 仅代表资源的实体,并不代表它的表述。如:有些URL最后的.html 后缀名并属于表述范畴,表述应该在HTTP请求的头信息中用 Accept和Content-Type 字段来指定。这两个字段才是对“表述”的描述。
状态转移:(State Transfer)是指在客户端同服务端交互的过程中。客户端能够通过资源的表述,实现操作资源的目的。当我们使用浏览器访问一个网站时,就代表了客户端和服务器端的一个交互过程。在这个过程中,必然会涉及数据或者状态的变化。但是我们知道HTTP是一个无状态的协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作资源,必须通过某种手段,让服务器端发生状态的转移。而这种转移是建立在资源的表述上的。所以通常将其称为表述层状态转移。
统一接口:(Uniform Interface)客户端操作资源的方式,通常是基于HTTP的4个动词(Verb):GET、POST、PUT、DELETE。它们分别对应4种资源的操作方式。
GET:用来获取资源
POST:用来新建资源
PUT:用来更新资源
DELETE:用来销毁资源
因为客户端是通过HTTP的这4个动词操作资源的。也就意味着不管请求的URI是什么,请求的资源有什么不同,但操作资源的接口都是统一的。
3.3 REST的优势
通过资源表述、状态转移以及统一接口,REST 将客户端的请求、服务器端的响应基于资源联系起来,逐渐形成了一种以资源为核心、以HTTP为操作方式的、与语言无关、平台无关的通信机制。同时,由于HTTP本身的无状态性,使用REST,能够有效保持服务/应用的无状态性,利于将来的水平伸缩。
3.4 REST的不足
随着团队或者组织业务的不断增长,服务器端响应内容复杂度的增加,REST的使用面临如下的挑战:
1:如何标准化资源结构
2:如何处理资源的相关链接
3.4.1 如何标准化资源结构
使用REST可以将业务场景的具体信息定义为资源。并基于JSON或者XML返回给客户端,随着业务的不断增长,逻辑的增加,服务器端对内容的响应结构会变得越来越复杂(所谓响应结构,是指服务器端的响应内容结构,既资源的结构)
REST作为指导性的原则,并没有定义服务器端响应结构应该遵循什么标准。这也就意味着在企业内部、不同的部门、不同的开发小组,对同一类资源所定义的结构可能不同,因此如何定义一套标准的资源响应结构,成为服务数量增多后使用的REST面临的一个挑战。
3.4.2 如何有效处理相关资源的链接
大部分REST的实现,都是基于 JSON 作为传输格式,但 JSON最大的遗憾在于没有对超链接处理做内置的支持,而这部分却恰恰是 Web 的基石,这带来的潜在问题是,对于调用接口的客户端而言,每次需要查看相关的接口文档,才能了解如何修改资源的状态,或者获取相关联资源的信息。因此,如何用有效的方式管理REST中相关资源的依赖以及链接,是否能够将这种方式标准化,成为服务数量增多后使用REST面临的另一个挑战。
3.4.3 其他需要考虑的因素
性能:
由于REST 是基于 HTTP 之上的协议,而HTTP本身是一个使用广泛的、基于TCP/IP的应用层协议,因此 REST 并不是低延时通信的最好选择。对于服务之间对低延时要求的场景,可能需要选择不同的底层协议,如UDP 来达到希望的性能,或者其他RPC框架
开发成本:
使用REST,其传输格式是XML或者JSON的文本格式,在享受平台无关、语言无关优势的同时,团队需要编写更多的代码来解析文本格式的协议,不过目前已经有很多成熟的库帮助我们来做类似的事情,如 Java下解决 JSON的 JSON-lib、org.json 以及 C# 下的 Newtonsoft.Json
说明:
1、参考书籍:《分布式服务架构:原理、设计与实战》《微服务架构与实践》
2、如有不合适的地方请反馈。综合后更改。