02 异步通讯设计

一、 了解

  • 隔离设计对系统做了解耦设计,把一个单体系统解耦,对系统进行了拆分,拆分完后会面对很多问题,其中最重要的就是系统的通讯。

1 通讯分类

  • 通讯一版来说分为同步和异步两种。
    • 同步通讯实时响应。实时性也会比异步调用搞。
    • 异步通讯 面对超搞吞吐量的场景下,异步处理比同步处理有比较大的优势。

1. 同步调用带来的问题

  1. 被调用方的吞吐量不低于调用方的吞吐量,否则被调用方因为性能不足拖死调用方。
    • 整个同步调用链的性能会由最慢的那个服务所决定。
  2. 同步调用会导致被调用方一直在等待调用方完成,如果一层一层同步调用下去,所有参与方会有相同等待时间。
    • 这会非常耗调用方的资源,因为调用方需要保存现场等待远端返回,所以对于并发比较高的场景来所,这样的等待可能会极度消耗资源。
  3. 同步调用只能是1对一的,很难做到1对多。
  4. 被调用方如果有问题,调用方也会跟着出问题,会出现多米诺骨牌效应,故障一下就蔓延开来。

2. 异步调用的好处

  1. 增加系统的吞吐量
  2. 可以让服务间的解耦更加彻底,系统的调用方和被调用方可以按照自己的速率而不是步调一致,可以更好的保护系统,让系统更加有弹力。

二、异步通讯

1. 异步通讯的三种方式

1. 请求响应式

  • 发送方会直接请求接收方,被请求方接收到请求方后,直接返回--收到请求,正在处理。
  • 返回结果,有两种处理方法
    1. 发送方 时不时的去轮询一下, 问一下干没干完。
    2. 发送方注册一个回调方法,也就是 接收方处理完回调请求方。
      • 这种架构模型,网上支付中常见。
        • 页面先聪上架跳转到支付宝或银行,商家会把回调的URL传给支付页面,支付完后,再跳转回商家的URL
  • 这种还是有一定耦合,发送方依赖了接收方,并且要把自己的回调发送给接收方,处理完回调。

2. 通过订阅的方式

  • 接收方会来订阅发送方的消息,发送方会把相关的消息或数据放到接收方所订阅的队列中。而接收方会从队列中获取数据。
    • 这种方式 发送方,不关心订阅方的处理结果,它只是告诉订阅方有事要干,收到消息后 给个ACK就好。这个方式常用于像MVC这样的设计模式。
  • 这个方式下,接收方需要向发送方订阅事件,所以是接收方依赖于发送方。这种方式还是有一定耦合。

3. 通过Broker 的方式

  • 所谓 Broker,就是一个中间人,发送方(sender)和接收方(receiver)都互相看不到对方,它们看得到的是一个 Broker,发送方向 Broker 发送消息,接收方向 Broker 订阅消息。

    • 所有服务都不需要互相依赖,而是依赖一个中间件 Broker,这个 Broker 是一个像数据总线一样的东西,所有的服务要接收数据和发送数据都发到这个总线上,这个总线就像协议一样,让服务间的通讯变得标准和可控。
  • 这种模式,发送方的服务和接收方的服务最大程序的解耦。但是所有人都依赖与一个总线,所以这个总线就需要有如下特征:

    1. 必须是高可用的,因为它乘务了整个系统的关键
    2. 必须是高性能而且是可以水平扩展的
    3. 必须是可以持久化不丢数据的。

2. 事件驱动设计

  • 上面二,三种就是比较著名的事件驱动架构。事件驱动最好是使用Broker方式,服务间通过交互消息来完成交流和整个流程的驱动。

1. 事件驱动方式的好处。

  1. 服务间的依赖没有了,服务间是平等的,每个服务都是高度可重用可被替换的。
  2. 服务的开发,测试,运维,以及故障处理都是高度隔离的。
  3. 服务间通过事件管理,所以服务间是不会互相block的
  4. 在服务间增加一些Adapter(如日志、认证、版本、限流、降级、熔断等)相当容易。
  5. 服务间的吞吐也被解开了,各个服务可以按照自己的处理速度处理。

2. 事件驱动不好的地方

1.业务流程不再那么明显和好管理。整个架构变得比较复杂。解决这个问题需要有一些可视化的工具来呈现整体业务流程。
2.事件可能会乱序。这会带来非常 Bug 的事。解决这个问题需要很好地管理一个状态机的控制。

  1. 事务处理变得复杂。需要使用两阶段提交来做强一致性,或是退缩到最终一致性。

3. 异步通讯的设计重点

1. 为什么要异步通讯

  1. 异步通讯最重要的是解耦服务间的依赖。最佳解耦的方式是通过 Broker 的机制。
  2. 解耦的目的是让各个服务的隔离性更好,这样不会出现“一倒倒一片”的故障。
  3. 异步通讯的架构可以获得更大的吞吐量,而且各个服务间的性能不受干扰相对独立。
  4. 利用 Broker 或队列的方式还可以达到把抖动的吞吐量变成均匀的吞吐量,这就是所谓的“削峰”,这对后端系统是个不错的保护。
  5. 服务相对独立,在部署、扩容和运维上都可以做到独立不受其他服务的干扰。

2. 设计成异步通信的时候需要注意事宜

  1. 用于异步通讯的中间件 Broker 成为了关键,需要设计成高可用不丢消息的。另外,因为是分布式的,所以可能很难保证消息的顺序,因此你的设计最好不依赖于消息的顺序

  2. 异步通讯会导致业务处理流程不那么直观,因为像接力一样,所以在 Broker 上需要有相关的服务消息跟踪机制,否则出现问题后不容易调试。

  3. 因为服务间只通过消息交互,所以业务状态最好由一个总控方来管理,这个总控方维护一个业务流程的状态变迁逻辑,以便系统发生故障后知道业务处理到了哪一步,从而可以在故障清除后继续处理。

    • 这样的设计常见于银行的对账程序,银行系统会有大量的外部系统通讯,比如跨行的交易、跨企业的交易,等等
      • 为了保证整体数据的一致性,或是避免漏处理及处理错的交易,需要有对账系统,这其实就是那个总控,这也是为什么银行有的交易是 T+1(隔天结算),就是因为要对个账,确保数据是对的。
  4. 消息传递中,可能有的业务逻辑会有像 TCP 协议那样的 send 和 ACK 机制。比如:A 服务发出一个消息之后,开始等待处理方的 ACK,如果等不到的话,就需要做重传。此时,需要处理方有幂等的处理,即同一条消息无论收到多少次都只处理一次

你可能感兴趣的:(02 异步通讯设计)