详解微服务技术中进程间通信( 三 )


 
使用消息有诸多优点:
 

  • 把客户端从服务中解耦出来:客户端只需要简单的往正确的通道里发消息,它完全不用感知服务实例,它不需要通过发现机制来定位服务实例所在的位置 。
  • 消息缓冲:在使用HTTP这种同步的请求/响应协议时,客户端和服务都必须在交换数据的时候保持可用 。与此相反,消息代理会将写到通道里面的消息队列化,直到消费者能够处理这些消息 。这意味着,比如,对订单的消息进行简单的队列化之后,即使是订单填写系统响应缓慢或者不可用,一个在线商店仍然可以接收到来自客户的订单 。
  • 灵活的客户——服务交互:消息机制支持之前提到的所有交互风格 。
  • 显式的进程间通信:基于RPC的机制能够让调用远端的服务看起来如同调用本地服务,但由于存在物理规则和部分失败的可能,这些机制都有较大不同 。消息机制让这些不同之处变得很显式,这样程序员不用陷于安全失误当中 。
 
当然,消息机制也有缺点:
 
  • 额外的操作复杂性:消息系统是另外一个系统,必须安装,配置和操作,消息代理必须高可用,要不然整个个系统的可靠性将受到影响 。
  • 实现基于请求/响应的交互比较复杂:请求/响应风格的交互要求一些实现上的工作,每个请求消息必须包含一个应答通道ID和关联ID,服务将相关ID包含在响应的消息中,并发送到响应通道,客户端就通过这个相关ID来将响应和请求匹配起来 。使用IPC机制来直接支持请求/响应通常简单一些 。
 
现在我们已经讨论完了基于消息的IPC,接下来探讨一下基于请求/响应的IPC
 
同步的请求/响应IPC
在同步的、基于请求/响应的IPC机制中,客户端向服务发送一个请求,服务处理这个请求,并将响应发回 。在许多客户端的实现中,发送请求的线程会在等待响应的时候阻塞 。
 
而另一些客户端的实现,可能使用异步的、事件驱动的方式,请求相关的代码会被封装在Futrues或者Rx Observables这样的库中 。和前面介绍的消息机制不同,在这种IPC里客户端是假设响应会及时返回 。有很多协议可供选择,其中有两种很流行:REST和Thrift 。我们先来看看REST
 
REST
目前,使用RESTful风格来开发API是很流行的做法,REST是使用HTTP的IPC机制,REST的一个关键概念是资源,资源代表一个业务对象,比如说一个客户,一个产品,或者是一些业务对象的集合 。REST使用HTTP的方法来操作资源,通过URL来引用资源 。比如,GET请求会返回一个资源的信息,返回结果用XML文档或者JSON对象来表示,POST请求创建一个资源,PUT请求是更新一个资源 。REST的创建者Roy Fielding的描述如下:
 
“REST提供一个架构约束的集合,当被整体应用时,强调组件交互的扩展性、接口的普遍性,组件的独立部署,减少交互延时的中间组件,增强的安全性以及对遗留系统的封装 。”
 
下图展示了打车应用中使用REST的一个场景 。
 
详解微服务技术中进程间通信

文章插图
 
 
乘客的智能手机向行程管理服务发送创建行程的请求,这个时候一个POST请求发送到服务端,请求创建一个/trips资源,行程管理服务随后发送一个GET请求到乘客管理服务,来获取乘客的信息,在确认了这个乘客是一个授权过可以创建行程的用户之后,行程管理服务正式的创建出行程,并且返回一个201结果给智能手机 。
 
很多开发者都声称他们的HTTP API都是RESTful的,但如Fielding在他的这篇博客里描述的,其实他们不一定都是 。Leonard Richardson给出了一个很有用的REST成熟度模型,包含如下一些级别: