微信:我们绝不丢消息!

作者 : 码海拾光 本文共2005个字,预计阅读时间需要6分钟 发布时间: 2025-03-31 共41人阅读




微信:我们绝不丢消息!

《架构师之路:架构设计中的100个知识点》

49.消息可靠投递

有水友问我说,总感觉微信不丢消息,它是怎么做到的?

之前做过几十年IM架构,今天和大家聊聊消息的可靠投递IM系统中,报文分几种类型?
答,三种:

1. 请求报文(Request)

2. 应答报文(Acknowledge)

3. 通知报文(Notify)
Image 1: 图片
R:客户端主动发送给服务器的报文;
A:服务器被动应答客户端的报文,一个A对应一个R;
N:服务器主动发送给客户端的报文;

路人架构师如何设计消息投递流程?
一个没做过IM系统的路人架构师,他可能会这么设计消息投递流程:用户A给用户B发送“你好”:
Image 2: 图片
1. client-A向im-server发送msg:R;
2. im-server回复client-A一个msg:A;
3. 如果此时client-B在线,则im-server向client-B发送msg:N;

画外音:如果client-B不在线,im-server存储离线消息。

上述消息投递流程存在什么问题?
流程图中会发现,发送方client-A收到msg:A后,只能说明im-server成功接收到了消息,并不能说明client-B接收到了消息。

在若干场景下,可能出现msg:N包丢失,例如:
1. 服务器崩溃,msg:N包未发出;
2. 网络抖动,msg:N包被网络设备丢弃;
3. client-B崩溃,msg:N包未接收;

结论是悲观的:接收方client-B是否有收到msg:N,发送方client-A完全不可控。

那怎么办呢?

应用层的消息可靠投递,必须通过应用层的超时、重传、确认来保证。

首先,加入应用层的确认机制。

要想让发送方client-A确保接收方client-B收到了消息,必须让接收方client-B回复client-A一个消息的确认。这个应用层的确认流程,与消息的发送流程类似:
Image 3: 图片
4. client-B向im-server发送ack:R;
5. im-server回复client-B一个ack:A;
6. im-server向client-A发送ack:N;

至此,发送“你好”的client-A,在收到了ack:N报文后,才能确认client-B真正接收到了“你好”。

你会发现,一条“你好”的发送,分别包含上下两个半场,即msg的R/A/N三个报文,ack的R/A/N三个报文,这是IM系统中消息投递的核心。

还可能存在什么问题?
复杂的网络环境下,msg:N,ack:N这两个报文都可能丢失(服务器奔溃、网络抖动、客户端奔溃),此时client-A都收不到期待的ack:N报文,即client-A不能确认client-B是否收到“你好”,但这两个报文的丢失对应的业务影响又大有不同:

1. msg:N包丢失,业务结果是client-B没有收到消息;

2. ack:N包丢失,业务结果是client-B收到了消息,只是client-A不知道而已;

结论仍然是悲观的:client-A无法知晓具体是哪种情况**。**

那怎么办呢?

接下来,要加入超时与重传。

client-A发出了msg:R,收到了msg:A之后,在一个期待的时间内,如果没有收到ack:N,client-A会尝试将msg:R重发。

可能client-A同时发出了很多消息,故client-A需要在本地维护一个等待ack队列,并配合timer超时机制,来记录哪些消息没有收到ack:N,以定时重发。
Image 4: 图片
一旦收到了ack:N,说明client-B收到了“你好”消息,对应的消息将从“等待ack队列”中移除。

消息的重传会引入什么新的问题?

超时与重传机制可能导致client-B收到重复的消息。

那怎么办呢?

最后,client-B要引入消息的去重机制。

发送方client-A生成一个消息去重的msgid,保存在“等待ack队列”里,同一条消息使用相同的msgid来重传,供client-B去重,而不影响用户体验。

也就是说,系统层面,client-B其实收到了很多消息,而产品体验层面,用户并不知道。系统,就是在背后默默保证你体验的那个人!

总结:

1. IM系统通过超时、重传、确认、去重的机制来保证消息的可靠投递;
2. 一个“你好”的发送,包含上半场msg:R/A/N与下半场ack:R/A/N的6个报文;

3. 等待ACK队列,是超时重传的关键,重传的消息msgid相同;

4. 无法做到系统层面的不丢不重,只能做到业务层面的不丢不重;

知其然,知其所以然。

思路比结论更重要。

==全文完==

附录,近5年系列内容:

1. 架构篇,已完结:《80个经典架构问题!

2. IM篇,已完结:关于即时通讯架构的一切!

3. 架构篇,进行中:《架构设计中100个知识点》

4. AI,进行中:《deepseek原理应用与实践》

5. 知行合一篇**,规划中,**《1743天,299万…

讲技术的宝藏号,日更。

微信的消息是这么发送的吗,清楚的同学可以说一说?





发表回复