当我们跨多个微服务进行内部通讯的时候,异步消息和事件驱动至关重要。我们可能需要在不同的边界上下文中进行域模型的更新。
我们举个例子,比如 eShop 这个项目中,Ording 服务在下单的时候要和 Catelog 服务进行通讯进行库存的扣减操作,这个时候我们就需要一种方式来做这个事情,并且能够在发生故障的时候也能正常工作,也就说需要进行基于异步消息和最终一致性的通讯方式。
当使用基于消息的通讯方式的时候,进程中是采用的异步的方式通讯的。客户端向某个服务发送消息,如果这个消息需要回复,那么另一个服务会向客户端发送一个不同的消息,并且客户端会认为该消息不会立即被接收到,并且不存在响应,这就是一种基于消息的通讯方式。
消息由标题(name 或者 title)和内容(Body)共同构成。消息通常会通过一些异步协议进行发送(如AMQP,kafka协议)。
异步消息通讯有两种:一种是单接收者(端到端),另外一种是多接收者(广播)。
如果有同学对消息队列比较了解的话,这就是消息队列的两种典型使用方式。
基于消息的单接收者
单接收者也就是说是点到点的通讯,将消息使用队列等方式从一点发送的另外一点,并且该消息仅会被处理(消费)一次。这中间一个特殊情况就是,当队列在尝试从故障中恢复时候,有可能会多次发送相同的消息,客户端必须实现幂等性以便能够处理相同的消息一次。
单接收器消息通讯的方式适用于将异步命令从一个微服务发送到另一个微服务。如下图:
一旦开始使用了基于消息的通讯,你应该避免将基于消息的通讯和同步的HTTP通讯混合起来。
注意:当command来到客户端应用程序时候,它们可以实现为HTTP的同步命令。当你需要更高的可扩展性或者你业务流程中已经使用了基于消息的方式时,那么你就应该使用基于消息的通讯方式。