如何在分布式环境中实现消息的“已发送”、“已送达”、“已读”状态的最终一致性?

B2C Data Innovating with Forum and Technology
Post Reply
muskanislam99
Posts: 272
Joined: Thu Dec 26, 2024 5:46 am

如何在分布式环境中实现消息的“已发送”、“已送达”、“已读”状态的最终一致性?

Post by muskanislam99 »

如何在分布式环境中实现消息的“已发送”、“已送达”、“已读”状态的最终一致性?
如何使用消息队列处理分布式系统中的事件和状态更新?
分布式系统中消息状态的最终一致性实现机制是什么?
WhatsApp 消息状态更新的工作原理是什么?

在分布式环境中实现消息的“已发送”、“已送达”、“已读”状态的最终一致性,是像 WhatsApp 这样的大规模实时通讯应用必须解决的关键挑战。由于其端到端加密特性以及全球分布式架构,它不可能依赖于强一致性(强一致性会牺牲可用性和分区容错性)。相反,WhatsApp 采用了一套精巧的机制来确保这些状态的最终一致性。

1. 核心理念:事件驱动与异步处理
消息状态的更新被视为一系列事件,通过消息队列进行异步传递和处理,最终达到一致。

生产者: 消息发送方客户端或 WhatsApp 服务器本身(例如,处理消息发送请求的前端服务器)。
消费者: 专门负责处理和持久化消息状态更新的后端服务(例如,消息传递服务、状态更新服务)。
这是最基本的状态,表示消息已成功从发送方发出并到达 WhatsApp 服务器。

实现机制:
客户端操作: 用户在客户端点击“发送”按钮。
发送到服务器: 客户端尝试将加密后的消息发送到 WhatsApp 前端服务器。
服务器持久化和入队:
一旦消息成功到达 WhatsApp 服务器并被 白俄罗斯 whatsapp 数据库 持久化(例如,写入到分布式消息队列 Kafka 或其内部消息存储),服务器会立即向发送方客户端发送一个确认回执(ACK)。
同时,消息被放入待处理的消息队列中,等待进一步的投递和状态更新。
客户端更新: 客户端收到 ACK 后,将消息状态更新为“已发送”(显示单勾)。
一致性特点:
发送方客户端的“已发送”状态是最快达成的,因为它只依赖于消息成功到达服务器并被确认。

表示消息已成功送达接收方设备,但可能尚未被接收方查看。

实现机制:
消息投递: 后端的消息投递服务(作为消息队列的消费者)从队列中拉取消息,并将消息推送到接收方设备的 WhatsApp 客户端。
接收方确认:
接收方客户端成功接收到消息(即消息被下载到设备并成功解密)后,会立即向 WhatsApp 服务器发送一个**“送达确认回执”(Delivery Receipt/ACK)**。
即使接收方客户端处于离线状态,一旦其重新上线并下载了积压的消息,也会发送这个送达回执。
服务器更新状态:
WhatsApp 服务器收到送达确认回执后,会将此状态信息持久化到数据库中(更新消息的状态字段)。
然后,服务器会将此送达状态作为一个新的事件,推送到发送方客户端的消息队列或直接推送给发送方客户端(如果在线)。
发送方更新: 发送方客户端收到送达状态事件后,将消息状态更新为“已送达”(显示双勾)。
一致性特点:
这是最终一致性的典型体现。从消息发送到接收方设备,再到送达回执传回服务器并更新发送方客户端的状态,整个过程涉及多个异步步骤和网络延迟。
在特定时间点,发送方可能还未看到双勾,而接收方已经收到了消息。但最终,随着所有事件的传递和处理完成,状态会趋于一致。
消息队列在此处尤其重要,因为它确保了送达确认回执不会丢失,即使发送方服务或数据库暂时不可用,回执事件也会被保留并最终处理。

表示接收方已打开并查看了消息。

实现机制:
接收方查看: 接收方客户端检测到消息已被用户查看(例如,聊天界面滚动到该消息位置,或用户打开了该聊天)。
发送已读回执: 接收方客户端向 WhatsApp 服务器发送一个**“已读确认回执”(Read Receipt)**。
服务器更新状态:
WhatsApp 服务器收到已读确认回执后,将此状态持久化到数据库。
同样,服务器会将此已读状态作为一个新的事件,推送到发送方客户端。
发送方更新: 发送方客户端收到已读状态事件后,将消息状态更新为“已读”(显示蓝勾)。
一致性特点:
与“已送达”类似,これも也是一个典型的最终一致性过程。
用户体验上,可能会有轻微的延迟,例如发送方可能在几秒后才看到蓝勾,但接收方已经看过了消息。
5. 分布式环境中的关键机制
消息队列(Kafka 等): 贯穿整个流程。所有状态更新事件(Delivery Receipt, Read Receipt)都被视为消息,写入到消息队列中,由相应的消费者服务异步处理。这确保了事件的可靠传输、解耦和削峰填谷。
数据库(Cassandra 等): 消息及其状态存储在分布式数据库中。数据库的**最终一致性模型(如可配置的一致性级别)**允许快速写入和高可用性,而状态更新的传播由后台复制和应用层逻辑管理。
时间戳和版本号: 在处理状态更新时,系统会利用时间戳或版本号来解决潜在的冲突(例如,如果状态更新乱序到达),确保最新状态能够覆盖旧状态。
幂等性处理: 后端处理消息状态更新的服务必须设计为幂等。这意味着即使由于网络重传或系统重试导致同一个状态更新事件被处理多次,也不会产生错误的结果。
心跳机制和长连接: 客户端与服务器之间的长连接和心跳机制有助于实时检测客户端的在线状态,并更迅速地推送状态更新。
离线处理: 如果客户端离线,消息状态更新的事件会存储在服务器端,待客户端上线后同步推送。
通过这些机制的组合,WhatsApp 在全球范围内实现了消息状态的高可用、高吞吐和最终一致性,即使在部分故障或网络不稳定的情况下,也能保证用户消息状态的最终准确性。
Post Reply