三、《微服务:从设计到部署》--进程间通信IPC

交互方式:

在单体应用中,组件可通过语言级方法或者函数相互调用。相比之下,基于微服务的应用是一个运行在多台机器上的分布式系统。通常,每个服务实例都是一个进程。因此,服务必须使用进程间通信(IPC)机制进行交互。

 

一对一

一对多

同步

请求/响应

-

异步

通知

发布/订阅

异步

请求/异步响应

发布/异步响应

以下为一对一交互,包括同步(请求/响应)与异步(通知与请求/异步响应):

  • 请求/响应
    客户端向服务发出请求并等待响应。客户端要求响应及时到达。在基于线程的应用中,发出请求的线程可能在等待时发生阻塞。
  • 通知(又称为单向请求)
    客户端向服务发送请求,但不要求响应。
  • 请求/异步响应
    客户端向服务发送请求,服务异步响应。客户端在等待时不发生阻止,适用于假设响应可能不会立即到达的场景。

一对多交互,它们都是异步的:

  • 发布/订阅
    客户端发布通知消息,由零个或多个服务消费。
  • 发布/异步响应

   客户端发布请求消息,之后等待一定时间来接收消费者的响应。

演化API:

有时候,你必须对 API 作出大量不兼容的更改。由于你无法强制客户端立即升级,服务也必须支持较旧版本的 API 一段时间。如果你使用了基于 HTTP 的机制(如 REST),则一种方法是将版本号嵌入到 URL 中。每个服务实例可能同时处理多个版本。或者,你可以部署多个不同的实例,每个实例处理特定的版本。

处理局部故障:

在设计服务时必须考虑处理局部故障。以下是一个由 Netflix 给出的好方案。处理局部故障的策略包括:

  • 网络超时
    在等待响应时,不要无限期地阻塞,始终使用超时方案。使用超时方案确保资源不被无限地消耗。
  • 限制未完成的请求数量
    对客户端请求的某些服务,设置未完成请求的数量上限。如果达到了上限,发出的额外请求可以视为毫无意义,因此这些尝试需要立即失败。
  • 断路器模式
    追踪成功和失败请求的数量。如果错误率超过配置阈值,则断开断路器,以便后续的尝试能立即失败。如果出现大量请求失败,则表明服务不可用,发送请求将毫无意义。发生超时后,客户端应重新尝试,如果成功,则关闭断路器。
  • 提供回退
    请求失败时执行回退逻辑。例如,返回缓存数据或者默认值,可以是一组空白的推荐数据

异步、基于消息的通信:

当使用消息传递时,进程通过异步交换消息进行通信。客户端通过发送消息向服务发出请求。如果服务需要回复,则通过向客户端发送一条单独的消息来实现。由于通信是异步的,因此客户端不会阻塞等待回复。相反,客户端被假定不会立即收到回复。

有两种通道类型,分别是点对点(point‑to‑point)与发布订阅(publish‑subscribe):

  • 点对点通道发送一条消息给一个切确的、正在从通道读取消息的消费者。服务使用点对点通道,就是上述的一对一交互方式。
  • 发布订阅通道将每条消息传递给所有已订阅的消费者。服务使用发布订阅通道,就是上述的一对多交互方式。

同步的请求/响应 IPC:

当使用基于同步、基于请求/响应的 IPC 机制时,客户端向服务器发送请求。服务处理该请求并返回响应。在许多客户端中,请求的线程在等待响应时被阻塞。其他客户端可能会使用到异步、事件驱动的客户端代码,这些代码可能是由 Futures 或 Rx Observables 封装的。然而,与使用消息传递不同,客户端假定响应能及时到达。有许多协议可供选择,其中有两种流行协议分别是 REST 和 Thrift

消息格式:

如果你使用的是消息系统或 REST,则可以选择自己的消息格式。其他 IPC 机制如 Thrift 可能只支持少量的消息格式,甚至只支持一种。在任一种情况下,使用跨语言的消息格式都很重要。即使你现在是以单一语言编写微服务,你将来也可能会使用到其他语言。

总结:

微服务必须使用进程间通信机制进行通信。在设计服务如何进行通信时,你需要考虑各种问题:服务如何交互、如何为每个服务指定 API、如何演变 API 以及如何处理局部故障。微服务可以使用两种 IPC 机制:异步消息传递和同步请求/响应。为了进行通信,一个服务必须能够找到另一个服务。

 

posted @ 2022-08-16 14:32  小新超人  阅读(108)  评论(0)    收藏  举报