异步通讯设计-Asynchronous
异步通讯设计-Asynchronous
同步的优点:
系统间只耦合于接口
实时性也会比异步调用要高 同步的缺点:
同步调用需要被调用方的吞吐不低于调用方的吞吐。同步调用链的性能会由最慢的那个服务所决定。
同步调用会导致调用方一直在等待被调用方完成,如果一层接一层地同步调用下去,所有的参与方会有相同的等待时间。这会非常消耗调用方的资源。因为调用方需要保存现场(Context)等待远端返回,所以对于并发比较高的场景来说,这样的等待可能会极度消耗资源。
同步调用只能是一对一的,很难做到一对多。
同步调用最不好的是,如果被调用方有问题,那么其调用方就会跟着出问题,于是会出现多米诺骨牌效应,故障一下就蔓延开来。 异步调用的优点:
增加吞吐量之外
让服务间的解耦更为彻底,系统的调用方和被调用方可以按照自己的速率而不是步调一致,从而可以更好地保护系统,让系统更有弹力 异步通讯的三种方式:
请求相应式
a. 发送方轮询
b. 发送方设置回调
直接订阅
中间件broker订阅
延伸:
事件驱动设计,如订阅、broker
自包含”也就是没有和别人产生依赖
事件驱动的好处:
服务间的依赖没有了,服务间是平等的,每个服务都是高度可重用并可被替换的。
服务的开发、测试、运维,以及故障处理都是高度隔离的。
服务间通过事件关联,所以服务间是不会相互 block 的。
在服务间增加一些 Adapter(如日志、认证、版本、限流、降级、熔断等)相当容易。
服务间的吞吐也被解开了,各个服务可以按照自己的处理速度处理。
坏处:
业务流程不再那么明显和好管理。整个架构变得比较复杂。解决这个问题需要有一些可视化的工具来呈现整体业务流程。
事件可能会乱序。这会带来非常 Bug 的事。解决这个问题需要很好地管理一个状态机的控制。
事务处理变得复杂。需要使用两阶段提交来做强一致性,或是退缩到最终一致性。
为什么要做异步设计:
异步通讯最重要的是解耦服务间的依赖。最佳解耦的方式是通过 Broker 的机制。
解耦的目的是让各个服务的隔离性更好,这样不会出现“一倒倒一片”的故障。
异步通讯的架构可以获得更大的吞吐量,而且各个服务间的性能不受干扰相对独立。利用 Broker 或队列的方式还可以达到把抖动的吞吐量变成均匀的吞吐量,这就是所谓的“削峰”,这对后端系统是个不错的保护。
服务相对独立,在部署、扩容和运维上都可以做到独立不受其他服务的干扰。 异步架构注意点:
中间件 Broker 是关键,需要设计成高可用不丢消息的。
无序。因为是分布式的,所以可能很难保证消息的顺序,因此你的设计最好不依赖于消息的顺序。
业务处理流程不直观。因为像接力一样,所以在 Broker 上需要有相关的服务消息跟踪机制,否则出现问题后不容易调试。
因为服务间只通过消息交互,所以业务状态最好由一个总控方来管理。这个总控方维护一个业务流程的状态变迁逻辑,以便系统发生故障后知道业务处理到了哪一步,从而可以在故障清除后继续处理。例如银行的对账程序。
需要处理方有幂等的处理。消息传递中,可能有的业务逻辑会有像 TCP 协议那样的 send 和 ACK 机制。