IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

微信为什么不丢消息?

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

上一章和大家分享了《 http如何像tcp一样实时的收消息?》, 本章来聊一聊即时通讯(Instant Messaging,后简称im) 消息的可靠投递

一、报文类型

im的客户端与服务器通过发送报文(也就是网络包)来完成消息的传递,报文分为三种

请求报文(request,后简称为为R)

应答报文(acknowledge,后简称为A)

通知报文(notify,后简称为N),这三种报文的解释如下:

img_1024_01_1.png
R:客户端主动发送给服务器的报文
A:服务器被动应答客户端的报文,一个A对应一个R
N:服务器主动发送给客户端的报文

二、普通消息投递流程

用户A给用户B发送一个“你好”,流程如下:
img_1024_01_2.png

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不在线,则消息会存储离线)

三、上述消息投递流程出现的问题

从流程图中容易看到,发送方client-A收到msg:A后,只能说明im-server成功接收到了消息,并不能说明client-B接收到了消息。在若干场景下,可能出现msg:N包丢失,且发送方client-A完全不知道,例如:

1)服务器崩溃,msg:N包未发出

2)网络抖动,msg:N包被网络设备丢弃

3)client-B崩溃,msg:N包未接收

结论是悲观的:接收方client-B是否有收到msg:N,发送方client-A完全不可控,那怎么办呢?

四、应用层确认+im消息可靠投递的六个报文

upd是一种不可靠的传输层协议,tcp是一种可靠的传输层协议,tcp是如何做到可靠的?答案是:超时、重传、确认。

要想实现应用层的消息可靠投递,必须加入应用层的确认机制,即:要想让发送方client-A确保接收方client-B收到了消息,必须让接收方client-B给一个消息的确认,这个应用层的确认的流程,与消息的发送流程类似:
img_1024_01_3.png

4)client-B向im-server发送一个ack请求包,即ack:R

5)im-server在成功处理后,回复client-B一个ack响应包,即ack:A

6)则im-server主动向client-A发送一个ack通知包,即ack:N

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

会发现,一条消息的发送,分别包含(上)(下)两个半场,即msg的R/A/N三个报文,ack的R/A/N三个报文,一个应用层即时通讯消息的可靠投递,共涉及6个报文,这就是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发出了msg:R,收到了msg:A之后,在一个期待的时间内,如果没有收到ack:N,client-A会尝试将msg:R重发。可能client-A同时发出了很多消息,故client-A需要在本地维护一个等待ack队列,并配合timer超时机制,来记录哪些消息没有收到ack:N,以定时重发。

img_1024_01_4.png

一旦收到了ack:N,说明client-B收到了“你好”消息,对应的消息将从“等待ack队列”中移除。

七、消息的重传存在什么问题

第五章提到过,msg:N,ack:N都有可能丢失:

1)msg:N报文丢失,说明client-B之前压根没有收到“你好”报文,超时与重传机制十分有效

2)ack:N报文丢失,说明client-B之前已经收到了“你好”报文(只是client-A不知道而已),超时与重传机制将导致client-B收到重复的消息,那怎么办呢?

八、消息的去重

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

九、其他

1)上述设计理念,由客户端重传,可以保证服务端无状态性(架构设计基本准则)

2)如果client-B不在线,im-server保存了离线消息后,要伪造ack:N发送给client-A

十、总结

1)im系统是通过超时、重传、确认、去重的机制来保证消息的可靠投递,不丢不重

2)一个“你好”的发送,包含上半场msg:R/A/N与下半场ack:R/A/N的6个报文

3)im系统难以做到系统层面的不丢不重,只能做到业务层面的不丢不重

末了,微信的消息是不是这么发送的,偶不太清楚,清楚的同学可以说一说。

干货推荐

作者:58沈剑 | 来源公众号 | 架构师之路

文章永久链接:https://tech.souyunku.com/?p=10542


Warning: A non-numeric value encountered in /data/wangzhan/tech.souyunku.com.wp/wp-content/themes/dux/functions-theme.php on line 1154
赞(64) 打赏



未经允许不得转载:搜云库技术团队 » 微信为什么不丢消息?

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码
IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

评论 抢沙发

大前端WP主题 更专业 更方便

联系我们联系我们

觉得文章有用就打赏一下文章作者

微信扫一扫打赏

微信扫一扫打赏


Fatal error: Uncaught Exception: Cache directory not writable. Comet Cache needs this directory please: `/data/wangzhan/tech.souyunku.com.wp/wp-content/cache/comet-cache/cache/https/tech-souyunku-com/index.q`. Set permissions to `755` or higher; `777` might be needed in some cases. in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php:367 Stack trace: #0 [internal function]: WebSharks\CometCache\Classes\AdvancedCache->outputBufferCallbackHandler() #1 /data/wangzhan/tech.souyunku.com.wp/wp-includes/functions.php(5109): ob_end_flush() #2 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(303): wp_ob_end_flush_all() #3 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters() #4 /data/wangzhan/tech.souyunku.com.wp/wp-includes/plugin.php(470): WP_Hook->do_action() #5 /data/wangzhan/tech.souyunku.com.wp/wp-includes/load.php(1097): do_action() #6 [internal function]: shutdown_action_hook() #7 {main} thrown in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php on line 367