微服务架构中的进程间通信(进程间通信机制二)

二、基于异步消息模式的通信

1 消息传递

消息传递两种架构:基于消息代理(服务通信的基础设施服务)的架构、基于无代理的架构。

基于无代理的消息传递架构:服务直接通信

基于消息代理的消息传递架构:服务通过消息通道通信。发送方(应用程序或服务)将消息写入通道,接收方(应用程序或服务)从通道读取消息。

1.1 关于消息

1.1.1 概念

消息组成:头部+主体

消息头部内容:

1、标题是名称和值对的组合,描述正在发送的数据的元数据。

2、发件人或消息传递基础上设施生成的唯一消息ID

3、可选的返回地址(该地址指定发送回复的消息通道)

消息主体:以文本或二进制格式发送的数据。

1.1.2 消息类型

·文档:仅包含数据的通用消息。接收者决定如何解释它。对命令式消息的回复是文档消息的一种使用场景;

·命令:一条等同于RPC请求的消息。它指定要调用的操作及其参数;

·事件:表示发送方这一端发生了重要的事件。事件通常是领域事件,表示领域对象的状态更改。

1.2 关于通道

消息通道类型:点对点、发布-订阅

点对点通道向正在从通道读取的一个消费者传递消息,服务使用点对点通道来实现一对一交互方式。例如,命令式消息通常通过点对点通道发送。

发布-订阅通道将一条消息发送给所有订阅的接收方。服务使用发布-订阅通道来实现一对多交互方式。例如,事件式消息通常通过发布-订阅通道发送。

2 使用消息机制实现交互方式

2.1 请求/响应&异步请求&响应

通过在请求消息中包含回复通道和消息标识符来实现异步请求/响应。接收方处理消息,并将回复发送到指定的回复通道。

由于客户端和服务使用消息机制通信,因此交互本质上是异步的。

2.2 实现单向通知

客户端将消息(通常是命令式消息)发送到服务所拥有的点对点通道。服务订阅该通道并处理该消息,但是服务不会发回回复。

2.3 实现发布/订阅

客户端将消息发布到由多个接收方读取的发布/订阅通道,服务使用发布/订阅来发布领域事件,领域事件代表领域对象的更改。发布领域事件的服务拥有自己的发布/订阅通道,通道的名称派生自领域类。对特定领域对象的事件感兴趣的服务只需订阅相应的通道。

2.4 实现发布/异步响应

结合了发布/订阅和请求/响应

客户端发布一条消息,在消息的头部中指定回复通道,这个通道同时也是一个发布-订阅通道。

消费者将包含相关性ID的回复消息写入回复通道。客户端通过使用相关性ID收集响应,将回复消息与请求匹配。

服务的异步API包含供客户端调用的操作和由服务对外发布的事件。

服务的异步API由消息通道、命令、回复、事件消息类型组成。

3 使用消息代理

优点:

1、发送发不需要知道接收方的网络位置

2、消息代理缓冲消息,直到接收方能够处理它们。

每个消息代理都用自己与众不同的概念实现消息通道
消息代理 点对点通道 发布-订阅通道
JMS 队列 主题
Apache Kafka 主题 主题
基于AMOP的代理,如RabbitMQ 交换+队列 组播式交换和每客户端队列
AWS Kinesis
AWS SQS 队列 /

4 基于消息的架构会遇到的设计难题

4.1 处理并发和消息顺序

问题:如何在保留消息顺序的同时,横向扩展多个接收方的实例。

现代消息代理(Kafka和Kinesis)使用的常见解决方案:分片(分区)通道。

1、分片通道由两个或多个分片组成,每个分片的行为类似于一个通道;

2、发送方在消息头部指定分片键,通常是任意字符串或字节序列。消息代理使用分片键将消息分配给特定的分片(例如,可以通过计算分片键的散列来选择分片)

3、消息代理将接收方的多个实例组合在一起,并将它们视为相同的逻辑接收方。(例如,Kafka使用术语“消费者组”)。消息代理将每个分片分配给单个接收器。它在接收方启动和关闭时重新分配分片。

4.2 处理重复消息

大多数消息代理承诺至少成功传递一次消息。

解决方法:

1、编写幂等消息处理程序

应用程序的幂等性:即使这个应用被相同输入参数多次重复调用,也不会产生额外的效果。

2、跟踪消息并丢弃重复项

消息接收方使用message ID跟踪它已处理的消息并丢弃任何重复项(专表或应用程序表记录)

 笔记来自:《微服务架构设计模式》一书,作者 [美] 克里斯·理查森 著,喻勇译  第三章

你可能感兴趣的:(微服务架构)