3.3.2 异步通信
与同步方式迥异的是,异步通信方式中无须一直等待被调用服务的响应。在这种通信模式中,调用方服务发布请求之后,可以继续完成其后续工作。类似的机制下,调用方服务也有自己的监听器,用来监听其他服务发给该服务的异步请求。监听器会抓取到这些请求并进行处理。异步模式的好处是无阻塞,也不用等待响应。一般而言,这种通信模式会用到消息代理。调用方服务只关心自己的消息是否正确发出了,然后就能继续后续工作了。这种方式下,即使被调用服务根本没有启动也不会影响调用服务。异步通信方式下,各个微服务实现了高度解耦,每个服务不用知道其他服务是否存在。
这种工作模式有一个假设的前提是,在单个服务内处理请求时,一般不需要来自其他服务的数据。特殊情况下,如果这个服务确实需要一些其他服务的数据,那么主要服务在完成自身部分的处理逻辑后,会通过消息通知其他相关的连带服务,如果连带服务也需要这部分主要服务的数据,可以在收到消息后在其自己的上下文中使这部分数据冗余。这样一来在某些时刻,主要服务与连带服务中的数据会出现不一致,但最终数据是能达到一致的。
最终一致性是一个用于在分布式计算中获得高可用的一致性模型。最终一致性可以非正式确保一旦某个数据没有新的更新操作,最终的所有对于该数据的访问都会获得该数据最终修改之后的值。1.基于消息/事件的异步通信异步通信的主要概念是消息从一个点流向另外一个点的过程。这些消息可以是一些命令、事件或者驱动信息等。典型的异步通信有两种类型:
基于消息的异步通信;
基于事件的异步通信。
这两种类型的工作方式较为类似。某个被调用的服务在完成其自身部分工作之后会触发一条消息,通知其他服务开始后续工作。这两种类型的区别定义得不是很清晰,但是一般而言基于消息的通信是点对点通信的,而基于事件的通信通常是一种发布/订阅模式。在消息驱动型通信中,聚合是通过预定义的消息队列或者通道来完成的。而在事件驱动或者基于命令的通信方式中,预先定义的格式应该是所有服务共享的消息驱动模式如图3-5所示,服务A向预定义的队列发布了一条消息,也就是说,逻辑上来讲服务A此时是知道服务B的存在的,服务A知道服务B会监听这个队列中的消息然后根据消息内容进行后续动作。
而在事件驱动的通信方式中,服务A发出一个事件之后,就可以忘记该事件了。这个发布出来的事件可能会被服务B使用,也可能被服务D使用,还有可能会被一个最近才刚启动的新服务使用,甚至某些时候可能没有任何服务会读取这个事件,也就是说事件驱动模式与基于消息的通信模式是略有些不同的。事件驱动的通信方式如图3-6所示,服务A完成其工作之后只管发布事件,而不用关心是否有其他服务会用到这个事件。在消息驱动模式中服务A是知道服务B一定会监听消息的,因此服务A放到消息中的数据应该只有服务B能够解析,或者这部分数据只对B有用。而在事件驱动方式中,完成的工作应该有一个统一的事件和数据格式,有了这种统一的格式才能够让任何一个服务或者后面新加的服务正确理解和使用。因此,事件驱动的通信方式中,很重要的一点是消息或事件的格式应该对所有服务都是一样的统一格式。图3-6描述了事件驱动的这个场景。
由于这两种方式区别不是很大,从现在开始我们将这两种异步通信方式并称为消息驱动的通信方式。总的看来,消息驱动的异步通信方式有下面这些优点。
因为使用异步通信方式使服务之间实现了高度解耦,所以第一个显而易见的好处是各个服务的扩展会更加灵活自如。新开发出来的微服务可以悄无声息地加入整个架构中来接收一些消息/事件,然后有针对性地做出一些行为。消息的发起方根本就不用关心接收消息的到底有哪些微服务。
在消息驱动型通信方式中,回压可以用一种比同步通信更好的方式得到解决。如果消息的产生方生成消息过快,超过了消费者的消费速度,就会有大量的消息堵塞在队列中等候处理。这种情形就是所谓的回压。在出现回压的时候,消费者可以做两件事:一是通过发布一个特殊事件来告诉生产方减缓速度,二是静静地添加更多的工作单元来加快消费速度。这类问题通常会出现在事件处理过程中。当然异步通信方式也有其弊端。
运行的复杂性会增加运维成本,因为需要额外安装、配置和维护高可用的消息代理。
观察系统中某个时间点的准确状态变得更加困难,因为消息流和事件会分发到很多不同的服务中去,因为微服务的自治性,所以想要了解清楚整个系统就更加困难。因此,在出现问题进行调试的时候也会需要更多的成本。
某些时候,将原本请求/响应结构转换成基于消息的模式是困难的。以一个火车票订票系统为例,如果不在订票之前检查有
没有空的座位,那么是无法正确受理订票请求的。也就是说这种有明显先后顺序的地方,使用同步方式更合理。
2.使用REST实现异步通信方式
异步通信方式既可以用REST风格的方式来实现,也可以用消息代理的方式来实现。如果用
REST风格来做的话,则需要一个作为消息处理中心的微服务。每个微服务将消息推送到这个处理中心,然后消息中心复杂将消息分发给相应的接收方微服务。在这种方式中,发起方的服务需要等待确认消息提交成功,但是并不需要等待被调用方的微服
务处理完整个业务之后的响应。其工作原理如图3-7所示。
当服务A完成其工作之后,提交给消息中心一个完成消息,消息中心有两种方式来将该消息发给被调用的其他服务。第一种方式是消息中心智能识别出该消息的接收方应该是哪个服务,然后将消息和数据准确地发送给该服务。另外一种方式是,消息中心直接将收到的消息分发给每一个在消息中心上注册的微服务,由每个微服务自己判断是应该忽略该消息还是采取后续动作。
原文网址:https://www.epubit.com/book/detail/27566
内容来源:异步社区;版权属【人民邮电出版社 异步社区】所有,转载已获得授权;未经授权,不得以任何方式复制和传播本书内容,如需转载请联系异步社区。