在跨多个微服务及其相关的域模型传播更改时,异步消息传递和事件驱动的通信至关重要。正如前面在讨论microservices和有界上下文(BCs)时所提到的,模型(用户、客户、产品、帐户等)对不同的microservices或BCs可能有不同的含义。这意味着当发生更改时,您需要某种方法来协调不同模型之间的更改。解决方案是基于异步消息传递的最终一致性和事件驱动通信。
使用消息传递时,进程通过异步交换消息进行通信。客户端通过发送消息向服务发出命令或请求。如果服务需要回复,它会向客户端发送另一条消息。由于这是一种基于消息的通信,客户端假定不会立即收到回复,并且可能根本没有响应。消息由头(标识或安全信息等元数据)和正文组成。消息通常通过异步协议(如AMQP)发送。
微服务社区中此类通信的首选基础设施是轻量级消息代理,它不同于SOA中使用的大型代理和编排器。在轻量级消息代理中,基础设施通常是“哑的”,仅充当消息代理,具有简单的实现,如RabbitMQ或云中的可伸缩服务总线(如Azure服务总线)。在这个场景中,大多数“智能”思维仍然存在于生成和消费消息的端点中,也就是在微服务中。
您应该尽量遵循的另一个规则是,在内部服务之间只使用异步消息传递,并且只使用从客户端应用程序到前端服务(API网关加上第一级微服务)的同步通信(如HTTP)。
异步消息通信有两种:单接收者消息通信和多接收者消息通信。以下各节提供了有关它们的详细信息。
与单个接收器的基于消息的异步通信意味着存在点对点通信,该点对点通信将消息准确地传递给从通道读取的某个消费者,并且消息仅被处理一次。但也有特殊情况。例如,在尝试从故障中自动恢复的云系统中,可以多次发送同一消息。由于网络或其他故障,客户端必须能够重试发送消息,而服务器必须实现一个等幂操作,以便仅处理一次特定消息。
单接收器基于消息的通信特别适合于从一个微服务向另一个微服务发送异步命令,如图18所示,该图说明了这种方法。
一旦开始发送基于消息的通信(使用命令或事件),就应该避免将基于消息的通信与同步HTTP通信混合使用。
图18 接收异步消息的单个微服务
注意,当命令来自客户端应用程序时,它们可以实现为HTTP同步命令。当您需要更高的可伸缩性或已经在基于消息的业务流程中时,应该使用基于消息的命令。