软件架构的一个原则就是高内聚低耦合,同样微服务也是这样。将各个模块单独划分,模块内实现“高度自制”,那么就带来一个问题,如何实现个微服务模块之间高效的通信呢?有两种基本方向即:同步方式和异步方式。直白一点来讲,同步通信就是发起一个远程服务调用后,调用方会阻塞自己等待整个操作的完成;异步通信调用方不需要等待操作的完成就可以返回,甚至不需要关心这个操作的完成与否。

对比两种通信方式总结下面几点:

同步通信方式

`优缺点 耦合度高 `

难易程度 相对简单

`使用范畴 高延迟 `
`协作风格 基于请求响应:客户端发起请求,然后等待响应 `

异步通信方式

`优缺点 耦合度低`
`难易程度 相对复杂`
`使用范畴 低延迟`
`协作风格 基于事件:客户端发起一个请求,然后注册一个回调,服务端操作完成之后调用该回调。`

微服务个模块规划,决定了使用那种通信方式。模块规划的一个目标就是尽量避免“上帝”服务(简政放权,打破中央集权),从而减少贫血的基于CURD的服务,这样的一个概念就是协同服务。使用协同服务可以降低耦合度,并且可以对现有系统灵活的修改。这种架构设计每个服务足够完善,并且能很好的完成自己的任务。但万事总有两面性,首先设计过程中要避免过度自制,从而让整个架构过于零散不成体系。其次,我们确实需要额外的工作对业务流程做夸服务的监控和调度。
下面我们来一次分析两种实现方式即请求响应和基于事件两种方式的常用技术。

请求响应:

RPC(Remote Procedure Call)远程过程调用

简单来说远程过程调用允进行一个本地调用,但实际上是由某个远程服务器产生的。RPC的主要特点:帮你成服务端和客户端代码的桩代码,从而让你快速开始编码。在使用RPC架构的过程中,需要注意以下几个方面的问题:

  • 技术耦合:有一些RPC机制和平台紧密绑定,比如JavaRMI,因此只能基于Jvm来做客户端和服务端;有以下几个常用的Thrift, buffers等对不同的语言支持很好,从而降低的技术耦合度。
  • 本地调用和远程调用不同:RPC的核心方法是隐藏远程调用中的实现细节和复杂性,仿佛就是在调用本地应用一样,远程调用基于网络通信,所需要的时间往往比本地调用需要花费不止一个数量级。
  • 脆弱性:通常服务端一些修改有很大可能需要修改客户端的。
    看了上面这几点,可能会说RPC很糟糕,这样的问题可能跟某个具体的实现项目有关,比如Java RMI,而更现代的一些实现就会好很多,比如Thrift prorocol buffers等。

在做技术选型的时候,需要关注下面几个方面:

  • 不要对远程调用过度抽象
  • 独立升级服务端的接口而不需要客户端升级
  • 在客户端实现过程中一定不要隐藏做网络调用这个事实
    REST(Repreesentaional State Transfer)表述性状态转移,是一种手web启发而产生的一种架构风格。概念性的理解可以看一下阮一峰《理解RESTful架构》(http://www.ruanyifeng.com/blog/2011/09/restful)这片文章。简单来说,RESTful架构就是将web和传统本地软件结合,可以称之为互联网软件架构。这里直接摘录一段:

要理解RESTful架构,最好的方法就是去理解Representational State
Transfer这个词组到底是什么意思,它的每一个词代表了什么涵义。如果你把这个名称搞懂了,也就不难体会REST是一种什么样的设计。

三、资源(Resources)

REST的名称"表现层状态转化"中,省略了主语。"表现层"其实指的是"资源"(Resources)的"表现层"。
所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。
所谓"上网",就是与互联网上一系列的"资源"互动,调用它的URI。

四、表现层(Representation)

"资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现层"(Representation)。
比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。
URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html"后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴,而URI应该只代表"资源"的位置。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对"表现层"的描述。

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

互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State
Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。
客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

六、综述 综合上面的解释,我们总结一下什么是RESTful架构:   

1)每一个URI代表一种资源;
2)客户端和服务器之间,传递这种资源的某种表现层;
3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

事件的异步协作方式:

基于事件的通信主要考虑两方面:微服务的事件发布机制和消费者事件接收机制。
一般来讲我们会使用想RabbitMQ,MQTT等这样的消息队列,来解决生产者和消费者问题。通常这类是系统能提供丰富且准确的功能,具有较好的伸缩性和弹性能很好的实现松耦合和事件驱动。 但维护并学习使用这样一套系统的成本同样高昂。

另外一种就是ATOM这样的规范协议(说实话这个我也没听说过,《微服务设计》这本书提到顺便喽一眼,有想具体了解的自己查资料)。
个人来说还是推荐第一种方式,毕竟好的架构目标是易升级维护实现快速,如果技术成本太高还是借鉴学习成本低并且也可接受的方案。

Tags: 微服务, 模块架构

Related Posts:
  • [尚无相关文章]

Leave a Comment