IPC
在微服务架构里,一个软件应用是基于一组独立的服务构建的。 因此为了实现某个应用场景,需要不同微服务、进程之间的通讯机制。这也是微服务之间跨服务、进程通讯这么重要的原因。
IPC即进程间通信(Inter-Porcess Communication)。微服务架构中有两类IPC机制可选:异步消息机制和同步请求/响应机制
定义API
服务API是服务与客户之间的契约。服务定义和你选择哪种IPC机制息息相关,如果你是要消息机制,API就由消息频道和消息类型组成;如果你使用http,API就是由URLs以及request/response格式组成。
API进化
服务API将会不可避免的随着时间进化,在传统单体应用中,我们可以很直接的去修改服务并更新所有服务的调用者(refactor)。但是在基于微服务架构的应用中,哪怕服务API的其他消费者都是在一个应用中,去更新所有服务也是相当困难的。你通常不能强制让所有的客户端升级来保持和服务端升级维持步调一致,而且,你还可能会增量部署新服务使得新老服务同时运行,寻找一种处理此种情况的策略是很重要的。
你是如何根据更改的大小来处理服务API的变化的呢?一些变化很小,通常可以与之前版本做到向后兼容,比如,你为请求或相应添加了一个属性;对此,设计服务时考虑服务和客户消费者的鲁棒性原则是很有必要的:使用旧版本服务API的客户端可以在新版本服务API下正常工作,服务端为客户端缺失的属性提供默认值,客户端自动忽略额外添加的响应属性。最后强调,注意使用IPC机制和定义消息格式使你的API可以简单方便的进化!
当然,有时候我们不得不对API做一些较大的,不再兼容的变化,而我们这时候又不可能强制每个客户端升级,因此我们的服务就要继续支持运行一段时间的老版本API。如果使用http,我们可以在URL里嵌入服务版本,每个服务实例可能同时处理多个版本的服务,当然,你也可以选择为每个服务版本部署单独的服务实例。
处理局部故障
- 网络超时:在等待响应时,不设置无限期阻塞,而是采用超时策略。使用超时策略可以确保资源不被无限期占用。
- 限制请求的次数:可以为客户端对某特定服务的请求设置一个访问上限。如果请求已达上限,就要立刻终止请求服务。
- 断路器模式(Circuit Breaker Pattern):记录成功和失败请求的数量。如果失效率超过一个阈值,触发断路器使得后续的请求立刻失败。如果大量的请求失败,就可能是这个服务不可用,再发请求也无意义。在一个失效期后,客户端可以再试,如果成功,关闭此断路器。
- 提供回滚:当一个请求失败后可以进行回滚逻辑。例如,返回缓存数据或者一个系统默认值。
服务间身份验证和授权
IPC技术
现在有很多不同的 IPC 技术。服务间通信可以使用同步的请求/响应模式,比如基于 HTTP 的 REST 或者 Thrift。另外,也可以选择异步的、基于消息的通信模式,比如 AMQP 或者 STOMP。此外,还可以选择 JSON 或者 XML 这种可读的、基于文本的消息格式。当然,也还有效率更高的二进制格式,比如 Avro 和 Protocol Buffer。在讨论同步的 IPC 机制之前,我们先了解异步的 IPC 机制。
异步消息机制
是基于消息进行通信的。一个消息由头部(元数据,如发送方信息)和消息体构成,消息通过channel发送。任何数量的生产者都可以发送消息到channel中,同样任何数量的消费者都可以从channel中接受数据。
交互模式
点对点
把消息准确地发送到某个会从channel中读取该消息的消费者。
发布/订阅
把消息投送到所有从channel中读取该消息的消费者。
异步消息机制的优点:
解耦,生成者只需要将消息发送到正确的channel上,完全不需要了解具体的服务实例。
消息缓冲,消息协商器将所有写入channel的消息按照队列方式管理,直到被消息者处理,这样的话,只要保证消息进入到消息队列中,即使系统很慢甚至暂时不可用也没关系,因为队列中会一直保存着这个消息。
客户端-服务端的灵活交互:消息机制支持以上说的所有交互模式。
清晰的进程间通信:基于 RPC 的通信机制试图让唤醒远程服务端像调用本地服务一样,然而,囿于物理定律和可能的局部失败,这二者大不相同。消息机制能让这些差异直观明确,开发者不会产生安全错觉。
异步消息机制的缺点:
额外的操作复杂性,消息系统需要单独安装、配置和部署。消息协商器必须要是高可用的。
实现基于请求/响应交互模式的复杂性:请求/响应交互模式需要完成额外的工作。每个请求消息必须包含一个回复渠道 ID 和相关 ID。服务端发送一个包含相关 ID 的响应消息到渠道中,使用相关 ID 来将响应对应到发出请求的客户端。这种情况下,使用一个直接支持请求/响应的 IPC 机制会更容易些。
同步请求/响应机制:
同步请求/响应是客户端向服务端发送一个请求,服务端处理请求,然后返回响应。
RESTful:
首先了解一下什么是REST?REST是一个资源,一般代表一个业务对象。RESTful API是基于HTTP的一种协议,使用HTTP语法协议来修改资源。
RESTful API成熟度模型:
- Level0的web服务只是使用HTTP作为传输方式,实际上只是RPC用的一种具体形式
- Level1的web服务引入了资源的概念,每个资源有对应的标识符和表达
- Level2的web服务使用不同的HTTP方法进行不同的操作,并使用HTTP状态码来表示不同的结果
- Level3的web服务使用HATEOAS,在资源的表达中包含了资源的链接信息,客户端可以 根据链接来发现可执行的动作
使用HTTP的优点:
- 简单且大家都熟悉
- 可使用浏览器扩展(如postman)或curl之类的命令来测试
- 内置支持请求/响应模式的通信
- 对防火墙友好
- 不需要中间代理,简化系统架构
使用HTTP的缺点:
- 只支持请求/响应模式交互
- 因为客户端与服务端直接通信,交互期间必须一直在线
- 客户端必须知道每个服务实例的URL
消息格式
在进程间通信必须选择一个能跨语言的消息格式。有两类格式:
文本:如JSON、XML 这类格式的优点在于可读性强,而且是自描述的。缺点就是消息会变得冗长,以及解析文本的负担过大。
二进制 这类格式的优点在于解码速度更快,效率更高。缺点在于可读性差。
参考文献
Building Microservices: Inter-Process Communication in a Microservices Architecture