【微服务系列】微服务总结(一)

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 最常见的服务发布和引用的方式有三种: RESTful API XML 配置 IDL 文件 1,RESTful APIRESTful API 的方式,主要被用作 HTTP 或者 HTTPS 协议的接口定义,即使 在非微服务架构体系下,也被广泛采用讲到RESTful API ,先去了解一下什么是RESTful 架构1.1 RESTful架构到底什么是REST...

 最常见的服务发布和引用的方式有三种:

RESTful API

XML 配置

IDL 文件

1,RESTful API

RESTful API 的方式,主要被用作 HTTP 或者 HTTPS 协议的接口定义,即使 在非微服务架构体系下,也被广泛采用

讲到RESTful API ,先去了解一下什么是RESTful 架构

1.1 RESTful架构

到底什么是RESTful架构,并不是一个容易说清楚的问题。下面,我就谈谈我理解的RESTful架构。

REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的。

Fielding是一个非常重要的人,他是HTTP协议(1.0版和1.1版)的主要设计者、Apache服务器软件的作者之一、Apache基金会的第一任主席。所以,他的这篇论文一经发表,就引起了关注,并且立即对互联网开发产生了深远的影响。

Fielding将他对互联网软件的架构原则,定名为REST,即Representational State Transfer的缩写。词组的翻译是"表现层状态转化"。

要理解RESTful架构,最好的方法就是去理解Representational State Transfer这个词组到底是什么意思,它的每一个词代表了什么涵义。

1,资源(Resources)

REST的名称"表现层状态转化"中,省略了主语。"表现层"其实指的是"资源"(Resources)的"表现层"。

所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。

所谓"上网",就是与互联网上一系列的"资源"互动,调用它的URI。

2,表现层(Representation)

"资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现层"(Representation)。

比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。

URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html"后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴,而URI应该只代表"资源"的位置。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对"表现层"的描述。

3,状态转化(State Transfer)

访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。

互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。

客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

综合上面的解释,总结一下什么是RESTful架构:

  (1)每一个URI代表一种资源;

  (2)客户端和服务器之间,传递这种资源的某种表现层;

  (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

2,XML 配置

接下来再来讲下 XML 配置方式,这种方式的服务发布和引用主要分三个步骤:

服务提供者定义接口,并实现接口。

服务提供者进程启动时,通过加载 server.xml 配置文件将接口暴露出去。

服务消费者进程启动时,通过加载 client.xml 配置文件来引入要调用的接口。

就这样,通过在服务提供者和服务消费者之间维持一份对等的 XML 配置文件,来保证服务 消费者按照服务提供者的约定来进行

服务调用。在这种方式下,如果服务提供者变更了接口 定义,不仅需要更新服务提供者加载的接口描述文件 server.xml,还需要

同时更新服务消 费者加载的接口描述文件 client.xml。

一般是私有 RPC 框架会选择 XML 配置这种方式来描述接口,因为私有 RPC 协议的性能要 比 HTTP 协议高,所以在对性能要求

比较高的场景下,采用 XML 配置的方式比较合适。但 这种方式对业务代码侵入性比较高,XML 配置有变更的时候,服务消费者

和服务提供者都 要更新,所以适合公司内部联系比较紧密的业务之间采用。如果要应用到跨部门之间的业务 调用,一旦有 XML

配置变更,需要花费大量精力去协调不同部门做升级工作。在我经历的 实际项目里,就遇到过一次底层服务的接口升级,需要所

有相关的调用方都升级,为此花费 了大量时间去协调沟通不同部门之间的升级工作,最后经历了大半年才最终完成。所以对于

XML 配置方式的服务描述,一旦应用到多个部门之间的接口格式约定,如果有变更,最好 是新增接口,不到万不得已不要对原

有的接口格式做变更。

现在突然想去了解一下,什么是PRC框架,以及RPC协议,下面去了解一下吧。

2.1 RPC框架

RPC(Remote Procedure Call Protocol)远程过程调用协议。一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。比较正式的描述是:一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。那么我们至少从这样的描述中挖掘出几个要点:

 

RPC是协议:既然是协议就只是一套规范,那么就需要有人遵循这套规范来进行实现。目前典型的RPC实现包括:Dubbo、Thrift、GRPC、Hetty等。这里要说明一下,目前技术的发展趋势来看,实现了RPC协议的应用工具往往都会附加其他重要功能,例如Dubbo还包括了服务治等功能。

网络协议和网络IO模型对其透明:既然RPC的客户端认为自己是在调用本地对象。那么传输层使用的是TCP/UDP还是HTTP协议,又或者是一些其他的网络协议它就不需要关心了。既然网络协议对其透明,那么调用过程中,使用的是哪一种网络IO模型调用者也不需要关心。

信息格式对其透明:我们知道在本地应用程序中,对于某个对象的调用需要传递一些参数,并且会返回一个调用结果。至于被调用的对象内部是如何使用这些参数,并计算出处理结果的,调用方是不需要关心的。那么对于远程调用来说,这些参数会以某种信息格式传递给网络上的另外一台计算机,这个信息格式是怎样构成的,调用方是不需要关心的。

应该有跨语言能力:为什么这样说呢?因为调用方实际上也不清楚远程服务器的应用程序是使用什么语言运行的。那么对于调用方来说,无论服务器方使用的是什么语言,本次调用都应该成功,并且返回值也应该按照调用方程序语言所能理解的形式进行描述。

 

RPC主要组成部分

image.gif编辑

Client:RPC协议的调用方。就像上文所描述的那样,最理想的情况是RPC Client在完全不知道有RPC框架存在的情况下发起对远程服务的调用。但实际情况来说Client或多或少的都需要指定RPC框架的一些细节。

Server:在RPC规范中,这个Server并不是提供RPC服务器IP、端口监听的模块。而是远程服务方法的具体实现(在JAVA中就是RPC服务接口的具体实现)。其中的代码是最普通的和业务相关的代码,甚至其接口实现类本身都不知道将被某一个RPC远程客户端调用。

Stub/Proxy:RPC代理存在于客户端,因为要实现客户端对RPC框架“透明”调用,那么客户端不可能自行去管理消息格式、不可能自己去管理网络传输协议,也不可能自己去判断调用过程是否有异常。这一切工作在客户端都是交给RPC框架中的“代理”层来处理的。

Message Protocol:在上文我们已经说到,一次完整的client-server的交互肯定是携带某种两端都能识别的,共同约定的消息格式。RPC的消息管理层专门对网络传输所承载的消息信息进行编码和解码操作。目前流行的技术趋势是不同的RPC实现,为了加强自身框架的效率都有一套(或者几套)私有的消息格式。

Transfer/Network Protocol:传输协议层负责管理RPC框架所使用的网络协议、网络IO模型。例如Hessian的传输协议基于HTTP(应用层协议);而Thrift的传输协议基于TCP(传输层协议)。传输层还需要统一RPC客户端和RPC服务端所使用的IO模型;

Selector/Processor:存在于RPC服务端,用于服务器端某一个RPC接口的实现的特性(它并不知道自己是一个将要被RPC提供给第三方系统调用的服务)。所以在RPC框架中应该有一种“负责执行RPC接口实现”的角色。包括:管理RPC接口的注册、判断客户端的请求权限、控制接口实现类的执行在内的各种工作。

IDL:实际上IDL(接口定义语言)并不是RPC实现中所必须的。但是需要跨语言的RPC框架一定会有IDL部分的存在。这是因为要找到一个各种语言能够理解的消息结构、接口定义的描述形式。如果您的RPC实现没有考虑跨语言性,那么IDL部分就不需要包括,例如JAVA RMI因为就是为了在JAVA语言间进行使用,所以JAVA RMI就没有相应的IDL。

不同的RPC框架实现都有一定设计差异。例如生成Stub的方式不一样,IDL描述语言不一样、服务注册的管理方式不一样、运行服务实现的方式不一样、采用的消息格式封装不一样、采用的网络协议不一样。但是基本的思路都是一样的,上图中的所列出的要素也都是具有的。

工业界的 RPC 框架一览

4.1、国内

Dubbo 。来自阿里巴巴 http://dubbo.I/O/

Motan 。新浪微博自用 https://github.com/weibocom/motan

Dubbox 。当当基于 dubbo 的 https://github.com/dangdangdotcom/dubbox

rpcx 。基于 Golang 的 https://github.com/smallnest/rpcx

4.2、国外

Thrift from facebook https://thrift.apache.org

Avro from hadoop https://avro.apache.org

Finagle by twitter https://twitter.github.I/O/finagle

gRPC by Google http://www.grpc.I/O (Google inside use Stuppy)

Hessian from cuacho http://hessian.caucho.com

Coral Service inside amazon (not open sourced)

上述列出来的都是现在互联网企业常用的解决方案,暂时不考虑传统的 SOAP,XML-RPC 等。这些是有网络资料的,实际上很多公司内部都会针对自己的业务场景,以及和公司内的平台相融合(比如监控平台等),自研一套框架,但是殊途同归,都逃不掉刚刚上面所列举的 RPC 的要考虑的各个部分。

 

2.2 RPC协议

RPC是一种远程过程调用的协议,使用这种协议向另一台计算机上的程序请求服务,不需要了解底层网络技术的协议。

在 RPC 中,发出请求的程序是客户程序,而提供服务的程序是服务器。

HTTP是一种超文本传输协议。是WWW浏览器和WWW服务器之间的应用层通讯协议。

RPC协议与HTTP协议的区别

RPC主要是基于TCP/IP协议的,而HTTP服务主要是基于HTTP协议的,我们都知道HTTP协议是在传输层协议TCP之上的,所以效率来看的话,RPC当然是要更胜一筹!下面来具体说一说RPC服务和HTTP服务。

OSI网络七层模型

在说RPC和HTTP的区别之前,我觉的有必要了解一下OSI的七层网络结构模型(虽然实际应用中基本上都是五层),它可以分为以下几层: (从上到下)

    • 第一层:应用层。定义了用于在网络中进行通信和传输数据的接口;
    • 第二层:表示层。定义不同的系统中数据的传输格式,编码和解码规范等;
    • 第三层:会话层。管理用户的会话,控制用户间逻辑连接的建立和中断;
    • 第四层:传输层。管理着网络中的端到端的数据传输;
    • 第五层:网络层。定义网络设备间如何传输数据;
    • 第六层:链路层。将上面的网络层的数据包封装成数据帧,便于物理层传输;
    • 第七层:物理层。这一层主要就是传输这些二进制数据。

    实际应用过程中,五层协议结构里面是没有表示层和会话层的。应该说它们和应用层合并了。我们应该将重点放在应用层和传输层这两个层面。因为HTTP是应用层协议,而TCP是传输层协议。好,知道了网络的分层模型以后我们可以更好地理解为什么RPC服务相比HTTP服务要Nice一些!

    1、RPC是一种API,HTTP是一种无状态的网络协议。RPC可以基于HTTP协议实现,也可以直接在TCP协议上实现。

    2、RPC主要是用在大型网站里面,因为大型网站里面系统繁多,业务线复杂,而且效率优势非常重要的一块,这个时候RPC的优势就比较明显了。

    HTTP主要是用在中小型企业里面,业务线没那么繁多的情况下。

    3、HTTP开发方便简单、直接。开发一个完善的RPC框架难度比较大。

    4、HTTP发明的初衷是为了传送超文本的资源,协议设计的比较复杂,参数传递的方式效率也不高。开源的RPC框架针对远程调用协议上的效率会比HTTP快很多。

    5、HTTP需要事先通知,修改Nginx/HAProxy配置。RPC能做到自动通知,不影响上游。

    6、HTTP大部分是通过Json来实现的,字节大小和序列化耗时都比Thrift要更消耗性能。RPC,可以基于Thrift实现高效的二进制传输。

    一般来说,RPC服务主要是针对大型企业的,而HTTP服务主要是针对小企业的,因为RPC效率更高,而HTTP服务开发迭代会更快。总之,选用什么样的框架不是按照市场上流行什么而决定的,而是要对整个项目进行完整地评估,从而在仔细比较两种开发框架对于整个项目的影响,最后再决定什么才是最适合这个项目的。一定不要为了使用RPC而每个项目都用RPC,而是要因地制宜,具体情况具体分析。

    3,IDL文件

    IDL 就是接口描述语言(interface description language)的缩写,通过一种中立的方式 来描述接口,使得在不同的平台上运行的对象和不同语言编写的程序可以相互通信交流。比 如你用 Java 语言实现提供的一个服务,也能被 PHP 语言调用。

    也就是说 IDL 主要是用作跨语言平台的服务之间的调用,有两种最常用的 IDL:一个是 Facebook 开源的Thrift 协议,另一个是 Google 开源的gRPC 协议。无论是 Thrift 协议 还是 gRPC 协议,它们的工作原理都是类似的。

    gRPC 协议的服务描述是通过 proto 文件来定义接口的,然后再使用 protoc 来 生成不同语言平台的客户端和服务端代码,从而具备跨语言服务调用能力。

    有一点特别需要注意的是,在描述接口定义时,IDL 文件需要对接口返回值进行详细定义。 如果接口返回值的字段比较多,并且经常变化时,采用 IDL 文件方式的接口定义就不太合 适了。一方面可能会造成 IDL 文件过大难以维护,另一方面只要 IDL 文件中定义的接口返 回值有变更,都需要同步所有的服务消费者都更新,管理成本就太高了。

    总结

    今天学习了服务描述最常见的三种方式:RESTful API、XML 配置以及 IDL 文件。 具体采用哪种服务描述方式是根据实际

    情况决定的,通常情况下,如果只是企业内部之间的 服务调用,并且都是 Java 语言的话,选择 XML 配置方式是最简单的。如果

    企业内部存在 多个服务,并且服务采用的是不同语言平台,建议使用 IDL 文件方式进行描述服务。如果 还存在对外开放服务调

    用的情形的话,使用 RESTful API 方式则更加通用

    image.gif

    相关文章
    |
    缓存 负载均衡 监控
    近期业务大量突增微服务性能优化总结-1.改进客户端负载均衡算法
    近期业务大量突增微服务性能优化总结-1.改进客户端负载均衡算法
    |
    监控 Dubbo Java
    分布式微服务学习总结——Hystrix
    分布式微服务学习总结——Hystrix
    分布式微服务学习总结——Hystrix
    |
    负载均衡 算法 前端开发
    分布式微服务学习总结——Ribbon和Feign
    分布式微服务学习总结——Ribbon和Feign
    分布式微服务学习总结——Ribbon和Feign
    |
    缓存 负载均衡 算法
    分布式微服务学习总结——Eureka详解
    分布式微服务学习总结——Eureka详解
    分布式微服务学习总结——Eureka详解
    |
    存储 安全 Java
    分布式微服务学习总结——分布式微服务概述
    分布式微服务学习总结——分布式微服务概述
    分布式微服务学习总结——分布式微服务概述
    |
    Ubuntu 关系型数据库 MySQL
    微服务之Docker知识点总结(三)
    微服务之Docker知识点总结()
    116 0
    微服务之Docker知识点总结(三)
    |
    关系型数据库 MySQL 应用服务中间件
    微服务之Docker知识点总结(二)
    微服务之Docker知识点总结
    96 0
    微服务之Docker知识点总结(二)
    |
    Ubuntu NoSQL 关系型数据库
    微服务之Docker知识点总结(一)
    微服务之Docker知识点总结
    137 0
    微服务之Docker知识点总结(一)
    |
    大数据 API 微服务
    又一神作!Alibaba“M8级”大牛总结微服务与事件驱动架构启蒙手册
    首先什么是事件驱动型微服务?(书中摘要) 微服务和微服务类型的架构已经存在很多年了,它们有许多不同的形式和名字。面向服务的架构(service-oriented architecture,SOA)通常由多个相互直接同步通信的微服务构成。消息传递架构使用可被消费的事件在微服务之间进行异步通信。基于事件的通信当然不算新颖,但大规模并实时地处理大数据集是新的需求,而这要求对旧的架构类型进行改进。
    又一神作!Alibaba“M8级”大牛总结微服务与事件驱动架构启蒙手册
    |
    监控 Cloud Native Java
    《JAVA生态圈技术总结》之 微服务架构蓝图总览(下)
    《JAVA生态圈技术总结》之 微服务架构蓝图总览(下)
    《JAVA生态圈技术总结》之 微服务架构蓝图总览(下)