数据流模式

兼容性是两个进程之间的关系:编码数据的进程和解码数据的进程。
那么问题来了,这两个进程是怎么交换数据的?

有三种主要的方式:

  • 通过数据库
  • 通过服务调用
  • 通过异步消息系统

通过数据库

兼容性在这种模式下可以用下图解释:

通过服务调用:REST 和 RPC

在某种程度上,服务和数据库很类似:都允许客户端提交并查询数据

不一样的是:数据库允许任意的查询语句,而服务只暴露一小部分事前决定好的接口。这种限制提供了一种接口级别的封装:客户端可以通过服务接口接触到什么粒度的数据。

微服务设计的一个重要目标是:通过让服务独立地部署和演进,使应用能更容易地改进和维护。

网络服务

当 HTTP 作为服务间的通信协议时,我们称之为网络服务

RPC 的问题

相比本地调用,RPC 存在以下这些问题:

  • 本地调用的过程是可预测的。而通过网络调用是不可预测的:网络问题非常非常常见。

  • 本地调用的结果是有限的而且可以预测的:返回结果,抛出异常或者什么都不返回(进程 crash)。而远程调用有各种各样的问题:你不知道是什么问题。

  • 远程调用的幂等性很难控制。

  • 远程调用的延迟时间相对来说很长。

  • 远程调用的参数和结果都需要被编解码,如果数据量大的话,将成为大问题。

  • 编程语言的不兼容。

RPC 目前的发展方向

一句话:在同一组织的内部使用。

通过公网调用的服务还是以 REST 为主。

RPC 中的数据编码和演进

由 RPC 的使用方式可以下结论:RPC 的服务方总是先于客户端更新。

因此:在 request 时总是需要向后兼容,在 resoponse 时需要考虑向前兼容。

总是使用 版本号 来控制兼容性。

消息机制数据流

和直接 RPC 调用相比,使用消息机制有下面这些好处:

  • 当接收方不可用或者过载了,message broker 可以作为一个 buffer 的存在。
  • 当接受方 crash 的话,可以通过 broker 重发以避免消息丢失。
  • 不需要发送方知道接收进程的 ip port。
  • 同一条消息可以被不同的接收者接收。
  • 逻辑上发送方和接收方是解耦的。

通常来说,发送方不会等待接收方的回应:fire and forget

message brokers

总的来说,message broker 是这样使用的:

一个进程将消息发送给一个 queue 或者 topic,broker 确保这条消息被转发至一个多个消费者。

一个 topic 只提供单向的数据流。

一条消息只是简单的字节序列:不需要复杂的数据模型。

分布式 actor 框架

actor 模型 是一种在单个进程中的并发编程模型。

核心理念是:把逻辑封装在 actors 中而不是直接处理线程。每个 actor 通常代表一个 客户端或者某种实体,每个 actor 都有一些和其他 actor 不共享的本地状态,actor 和其他 actor 通过发送和接收一部消息来通信。消息传送是不能被保证的:在出错的场景下,消息有可能丢失。由于每个 actor 在同一时间只能处理一个消息,因此不存在竞争的问题。

分布式 actor 框架中,这个编程模型的概念被扩大到节点的概念。

有三个著名的 actor 框架:

  • Akka
  • Orleans
  • Erlang OTP

好啦,第四章也看完啦。