Jack Jiang

我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
posts - 535, comments - 13, trackbacks - 0, articles - 1

     摘要: 本文由公众号“水滴与银弹”号主Kaito原创分享,原题“搞懂异地多活,看这篇就够了”,为使文章更好理解,即时通讯网收录时有修订。1、引言前几天技术群里有群友问我52im社区里有没有IM分布式系统异地多活方面的文章,我仔细想了想,除了微信分享的几篇文章里有提到容灾和异地多活(只是大致提过,没有详细展开),确实目前还没有系统性的异地多活技术资料可供参考。...  阅读全文

posted @ 2021-11-10 15:18 Jack Jiang 阅读(224) | 评论 (0)编辑 收藏

     摘要: 本文引用了ELab团队、腾讯大讲堂两个公众号分享的文章内容,引用内容见文末参考资料,感谢原作者的无私分享。1、引言对于市面上主流的IM来说,跟二维码有关的功能,比如扫码加好友、扫码登陆、扫码加群等,都是很常见的。这是微信的扫码登录功能:这是微信的扫码加好友功能: 二维码技术使用起来很简单,本系列的前三篇文章也专门针对IM扫码登录这个功能做了详细的分享,但本着学习技术不留死角的习惯,我认为...  阅读全文

posted @ 2021-11-01 19:49 Jack Jiang 阅读(172) | 评论 (0)编辑 收藏

     摘要: 本文由融云技术团队原创分享,原题“万字干货:IM “消息”列表卡顿优化实践”,为使文章更好理解,内容有修订。1、引言随着移动互联网的普及,无论是IM开发者还是普通用户,IM即时通讯应用在日常使用中都是必不可少的,比如:熟人社交的某信、IM活化石的某Q、企业场景的某钉等,几乎是人人必装。以下就是几款主流的IM应用(看首页就知道是哪款,我就不废话了):正...  阅读全文

posted @ 2021-10-26 14:41 Jack Jiang 阅读(163) | 评论 (0)编辑 收藏

本文由阿里闲鱼技术团队有攸分享,原题“向消息延迟说bybye:闲鱼消息及时到达方案”,有修订和改动,感谢作者的分享。

1、引言

IM消息作为闲鱼用户重要的交易咨询工具,核心目标有两点:

  • 1)第一是保证用户的消息不丢失;
  • 2)第二是保证用户的消息及时送达接收方。

IM消息根据消息的接收方设备是否在线,分为离线和在线推送。数据显示目前闲鱼每天有超过一半以上的IM消息是走在线通道的,而在线消息的到达率、及时性是直接影响用户体验的。

本文将根据闲鱼IM消息系统在消息及时性方面的优化实践,详细分析了IM在线通道面临的各种技术问题,并通过相应的技术手段来优化从而保证用户消息的及时到达。

PS:如果您对IM消息可靠性还没有概念,建议先阅读这篇入门文章《零基础IM开发入门(二):什么是IM系统的实时性?》。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170 [推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK

本文同步发布于:http://www.52im.net/thread-3726-1-1.html

2、系列文章

本文是系列文章的第5篇,总目录如下:

3、当前面临的问题

3.1 端内长连接中断

在IM场景中,用户与云端通信频繁,且为了实现用户的消息及时到达,往往采用云端下推消息的方式触达用户,所以用户在线时设备与云端会维持一条TCP长连接通道,可以更轻量级的与服务端进行交互,现代IM即时通讯的下行消息都是通过长连下发的。

当前闲鱼IM消息系统使用的是ACCS长连接,ACCS是淘宝无线提供的全双工、低延时、高安全的通道服务。

但由于用户设备网络状态的不确定性,可能会发生各种各样的网络异常情况导致ACCS长连接通道中断。而长连接一旦意外中断,就会导致用户无法及时收到在线消息。

针对这个问题,我们需要尽可能及时的感知到长连中断并尝试重连。具体的优化思路会在本文后面的内容中分享。

3.2 下推的消息未达

感知长连中断并重连只能在大多数时间保证长连接的有效性,但是在长连接无效或不稳定期间下推的消息客户端可能根本收不到。

简单说就是仅仅有重连机制无法保证下行消息必达,可能有以下场景导致下行消息失败:

  • 1)服务端发送下行消息时长连畅通,消息在传输路上通道断掉,客户端无法收到;
  • 2)设备的在线状态存在延迟,服务端下行消息时认为设备在线,实际上设备已经离线,无法收到;
  • 3)客户端收到了下行消息,但端上后续处理失败(比如落库失败,消息没有成功展示给用户)。

我们通过数据埋点统计得出,ACCS长连接的下行成功率在97%左右。

ACCS长连接的下行成功率的统计方法如下:

ACCS下行成功率 = 通过ACCS成功下行且客户端收到的消息量 / 服务端认为通过ACCS成功下行的消息量

有心急的同学就要问了,丢了3%的消息吗?

并没有!这3%的消息不会丢失,只是不保证及时触达给用户。

我们的消息同步模型是推拉结合模式,在用户拉取消息时会拉取到设备当前位点与服务端最新位点的所有消息,ACCS下行失败的消息会通过主动拉模式获取到,但客户端主动拉取消息的触发时机有限。

当前客户端主动拉取消息的触发时机主要有以下几个:

  • 1)用户冷启动app,主动同步消息;
  • 2)用户主动下拉刷新;
  • 3)app后台切换前台;
  • 4)收到一条推送消息,客户端发现新消息的位点跟本地最新的位点有gap,触发同步。

可见:上述主动同步消息的触发很大程度上依赖用户行为或者有没有收到新消息,难以保证消息及时到达。

如果是用户高频打开的IM软件,这样也不会有太大的问题。但是闲鱼app的活跃度较低,有时候甚至依赖IM消息拉活,而且一条延迟的消息触达可能导致用户错过一笔交易,闲鱼消息不允许有这样的延迟发生。

基于上述分析,我们先描述一个数据指标来反映现状。

通过上面的描述可知:ACCS消息并不全都是推下来的,也可能是主动拉下来的。如果是推,必定可以及时到达;如果是拉,则受限于用户行为。

拉的这部分消息,我们定义为ACCS消息补偿到达,然后计算ACCS消息补偿到达耗时,消息范围限定为服务端ACCS成功下行但是客户端通过主动拉取同步到的消息,以往的版本这个数据在60分钟左右。

注意:这个数据并不是消息触达到用户的耗时,因为如果在线转离线触达,拉取到消息的时间取决于用户行为(用户何时打开了app),但这个数据也能大致反映在线消息的到达延迟状况。

ACCS长连接的消息补偿到达耗时的统计方法如下:

ACCS消息补偿到达耗时 = 客户端通过拉获取到ACCS消息的时间 - 服务端ACCS下行时间

接下来本文将从长连接的重连和未达消息重发两个方面详细讲述我们是如何优化在线通道稳定性的,从而优化并保证消息的及时到达。

4、优化手段1:增加长连接重连机制

4.1 长连接为什么会中断?

有因必有果,我们先来分析下有哪些原因会导致连接中断。

对于IM这种场景下来说,通常可能有以下原因:

  • 1)用户设备断网;
  • 2)设备发生了网络切换;
  • 3)设备处于弱网环境,网络不稳定;
  • 4)设备网络正常,TCP连接由于NAT超时导致连接被运营商中断。

对于APP来说,如果是用户操作导致网络状态变化的情况,会有网络状态变化事件通知,这种情况可以监听事件并主动尝试重连。但现实中的大多数情况都是“意料之外”(正如上面列举的这些断网可能性一样)。

那么既然“意料之外”的断网无法预知,技术上可以如何有效的感知到各种异常状况呢?

PS:如果要透彻理解断网、弱网、TCP链接有效性,并不是本文能讲的清楚的,可以参照下面的资料深入理解一下,值得好好学习。

关于TCP链接本身的有效性问题,可以读以下两篇:

  1. 为何基于TCP协议的移动端IM仍然需要心跳保活机制?
  2. 不为人知的网络编程(十二):彻底搞懂TCP协议层的KeepAlive保活机制

关于移动网络的复杂性问题,可以从以下几篇入门的科普文章学习一下:

  1. IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!
  2. IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!
  3. IM开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!
  4. IM开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!

关于移动弱网带来的各种问题、优化方案等,可以通过以下几篇系统学习一下:

  1. 现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障
  2. 移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”
  3. 移动端IM开发者必读(二):史上最全移动弱网络优化方法总结
  4. 百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇

4.2 心跳检测机制

像大多数链路保活场景一样,IM这种场景下最有效的检测手段就是心跳检测(如果你对TCP链路保活还没有什么概念,建议先读《为何基于TCP协议的移动端IM仍然需要心跳保活机制?)。

原理就是:客户端通过定时发送心跳包,服务端收到心跳包后再反馈给客户端,通过客户端和服务端这一来一去的配合,就可以实现客户服和服务端各自都能感知到连接是否中断。

从及时性效果来看:心跳间隔越短越好,而频繁的心跳检测势必会带来用户流量以及电量的损耗,所以我们的实现目标是如何尽可能少的心跳检测而又尽量及时地感知到长连中断的意外情况。

状态机+消息心跳队列:

在心跳协议设计上,要注意心跳包的核心目标是检测长连通道是否畅通,客户端主动上行心跳包且能收到服务端回包,就认为长连通道健康。所以心跳的上行消息以及回包的数据包应尽可能小。一般来说,通过协议头标识心跳包及响应即可(这样就能节省协议包大小)。

PS:关于心跳机制的入门文章可以详读《一文读懂即时通讯应用中的网络心跳包机制:作用、原理、实现思路等》。

4.3 心跳策略

心跳策略是实现我们上述目标的核心机制,本文仅简单列举几种心跳策略。

比如以下这几种:

  • 1)短心跳检测 初始状态连续 ping 3次 收到 ACK 后,可以认为进入稳定状态;
  • 2)常规固定时长心跳(根据app状态不同,频率可调Mid+,Mid-, Long);
  • 3)自适应心跳 根据设备网络状态变化自动适应的心跳间隔;
  • 4)冗余心跳,app后台切前台,主动心跳一次。

关于心跳策略的详细设计甚至可以单独写一篇文章,有兴趣的同学可以阅读以下推荐的文章继续深入研究。

5、优化手段2:消息ACK应答与重发机制

5.1 概述

为了解决上面的问题,我们同时也引入了消息ACK应答与重发机制。

整体思路是:客户端在收到ACCS消息并处理成功后,给服务端回一个ACK应答包,服务端下发ACCS消息时将消息加入重试队列,收到ACK应答包后更新消息到达状态,并终止重试。

整体设计流程图如下:

该方案的难点即重试处理器的实现设计,接下来我们将重点讲述这部分的详细设计。

5.2 重试队列存储设计

我们采用阿里云表格存储TimeLine模型来存储下行消息的到达状态。Timeline 模型是针对消息数据场景所设计的数据模型,它能满足消息数据场景对消息保序、海量消息存储、实时同步的特殊需求,在IM、Feed流等消息场景应用广泛。(关于TimeLine模型,这里有篇详细的文章可以学习一下《现代IM系统中聊天消息的同步和存储方案探讨

我们给每个用户设备定义一个TimeLine,timeline-id定义为userId_deviceId,sequenceId自定义为消息位点。

存储结构如下:

每通过ACCS成功下行一条消息,则插入到接收用户设备的TimeLine中,收到ACK后根据消息id更新消息到达状态。

同时由于重试动作只发生在下行消息后较短的一段时间内,所以我们设置一个比较短的全局过期时间即可,避免数据膨胀。

5.3 延迟重试设计

如上图所示:

  • 1)每通过ACCS下发一条消息,先插入到Timeline中,初始状态为未达,然后生产一条延迟N秒的延迟消息;
  • 2)每次消费到延迟消息后,读取tablestore中该消息的到达状态,如到达则终止延迟,否则继续;
  • 3)每次重试先判断设备是否在线,如果设备不在线,转发离线通道并终止重试,如果设备在线,则重推未到达的消息,并再次延迟N秒消费;
  • 4)每条消息的重试生命周期中用的同一条延迟消息,最多重试消费M次,超过次数不再重试并打日志埋点(后续可以监控这种情况并基于这个数据进行优化)。

5.4 延迟重发策略

延迟重发策略是指在重发流程中,如何选择合适的延迟时间来使得重发的效率最高。

不同用户在不同时间、地点所处的网络环境差别较大,网络恢复到稳定态所需要的时间也有差异,需要选用合适的延迟策略来保证重发效率。

最优的延迟策略的目标是在最短的时间内,使用最少的重发次数将消息投递成功。以下是几种可选的方案。

5.4.1)固定延迟时间:

要想找到最优的延迟策略,必须从数据中通过分析得到答案,天马行空的想象往往离实际相差甚远。

我们先采用固定的延迟时间(10s)最大重试6次来分析一波数据:

通过这组数据可以看到:有约85%的消息在40s内重发可以投递成功,还有12%的消息在达到最大重试次数后依旧没有收到ACK。在4次重试之后,第5次成功只有2.03%,第6次只有0.92%,继续重发的收益已经变得很低。

6次以后还有部分消息没有收到ACK,这部分消息如果用固定延迟时间策略,性价比很低,频繁重发浪费系统资源,我们需要继续改进策略。

5.4.2)固定延迟+固定步长递增:

考虑到部分用户的网络短时间无法恢复,频繁的短间隔重发价值不大,我们采用4次固定短间隔延迟N秒后,每次延迟时间都是上一次延迟时间递增固定步长M秒的策略。直到收到ACK、用户设备离线或者达到了最大延迟时间MAX(N)。

这种策略一定程度上可以解决固定延迟时间重发策略的问题,但如果用户短时间网络无法恢复,每次重发都要重新递增,也不是一种最优解。

5.4.3)自适应延迟:

设计流程图:

如上图:我们最终衍生出了自适应延迟策略。

自适应延迟是指:根据用户的网络状况,采取自动调整的延迟时间,以期望达到最高的重发效率。

具体是:新消息先通过4次固定N秒的短延迟来探测设备的网络状况,一旦网络恢复,我们将设备的N值清空(设备N值是指根据上几次重发经验,当前设备网络能回复ACK所需要的最短时间,默认情况该值为空,代表用户设备网络正常)。4次重发后依旧收不到ACK,我们尝试读取设备N值,如果为空,则取初始值,以后每次延迟都递增固定步长M,并在重发后更新当前设备的N值,直到消息收到ACK或者达到了最大延迟时间MAX(N)。

5.5 新老版本兼容性

需要注意的是老版本的app是不会回ACK的,如果下发给老版本设备的消息也加入重试队列,那此类消息将一直重试到最大次数才会终止,无端消耗资源。

所以我们设计在ACCS长连建立之后,客户端主动上行一条设备信息,其中包含app的版本号,服务端存储一定时间,在将消息加入重试队列之前,先校验接收者设备app的版本号,符合要求再加入重试队列。

6、 最终优化后的效果

消息重连重发方案上线后,我们上面定义的指标 ACCS补偿到达时间 从60分钟大幅降低至15分钟,降幅达75%。

从而印证了我们的技术分析,同时用户有关消息延迟的舆情反馈大幅下降,可见消息重发机制对保证用户消息及时到达成效显著。

7、未来展望

消息在线通道的稳定性优化至此已告一段落,未来我们将继续优化闲鱼消息的使用体验,包括基础功能的完善以及基础体验的提升。

基础功能方面:我们在近期的版本中已经支持了消息撤回、草稿功能,后续将逐步支持发送定位,会话分组、备注,消息搜索等功能。

基础体验方面:我们对消息的UI样式做了优化升级,并优化了app消息tab页的cpu及内存使用,后续将继续从流量、电量、性能方面继续优化消息的使用体验。

附录:参考资料

[1] 为何基于TCP协议的移动端IM仍然需要心跳保活机制?

[2] 不为人知的网络编程(十二):彻底搞懂TCP协议层的KeepAlive保活机制

[3] 现代IM系统中聊天消息的同步和存储方案探讨

[4] 现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障

[5] 移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

[6] IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!

[7] IM开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!

[8] 移动端IM实践:实现Android版微信的智能心跳机制

[9] 融云技术分享:融云安卓端IM产品的网络链路保活技术实践

[10] Web端即时通讯实践干货:如何让你的WebSocket断网重连更快速?

本文已同步发布于“即时通讯技术圈”公众号。

同步发布链接是:http://www.52im.net/thread-3726-1-1.html

posted @ 2021-10-19 23:05 Jack Jiang 阅读(293) | 评论 (0)编辑 收藏

     摘要: 本文由作者“阿宝哥”分享,原题“你不知道的 WebSocket”,有修订和改动。1、引言本文将从基本概念、技术原理、常见易错常识、动手实践等多个方面入手,万字长文,带你一起全方位探索 WebSocket 技术。阅读完本文,你将了解以下内容:1)了解 WebSocket 的诞生背景、WebSocket 是什么及它的优点;2)了解 WebSocket 含...  阅读全文

posted @ 2021-10-11 14:35 Jack Jiang 阅读(185) | 评论 (0)编辑 收藏

     摘要: 本文由阿里闲鱼技术团队景松分享,原题“到达率99.9%:闲鱼消息在高速上换引擎(集大成)”,有修订和改动,感谢作者的分享。1、引言在2020年年初的时候接手了闲鱼的IM即时消息系统,当时的消息存在各种问题,网上的用户舆情也是接连不断。典型的问题,比如:1)“聊天消息经常丢失”;2)“消息用户头像乱了”;3)“订单状...  阅读全文

posted @ 2021-09-26 14:47 Jack Jiang 阅读(244) | 评论 (0)编辑 收藏

本文由阿里闲鱼技术团队今朝、有攸分享,本次有修订。

1、引言

闲鱼即时消息系统历经数代迭代,目前已能稳定的支撑亿级消息体量。

在此消息系统的建设过程中,我们经历了从简单到复杂、从困扰到破局,每一次的技术改变都是为了更好的解决当下业务所面临的问题。

本文分享的是闲鱼即时消息系统架构从零开始的技术变迁之路,以期更多的同行们在此基础上汲取经验,得到有价值的启发。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170 [推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK

本文同步发布于:http://www.52im.net/thread-3699-1-1.html )

2、系列文章

本文是系列文章的第3篇,总目录如下:

  1. 阿里IM技术分享(一):企业级IM王者——钉钉在后端架构上的过人之处
  2. 阿里IM技术分享(二):闲鱼IM基于Flutter的移动端跨端改造实践
  3. 阿里IM技术分享(三):闲鱼亿级IM消息系统的架构演进之路》(* 本文
  4. 阿里IM技术分享(四):闲鱼亿级IM消息系统的可靠性投递技术实践》(* 稍后发布

3、1.0版:业务初创期、最小化可用

3.1 技术背景

2014年启动闲置交易独立APP “闲鱼”,一期构建完成APP主链路,包含商品:发布→搜索→商品详情→IM会话→交易

作为初创app,业务需尽快上线验证效果,技术建设上需要完成闲鱼消息从无到有的系统搭建。

3.2 技术方案

作为即时通讯系统,最小化能力包含:

  • 1)消息存储:会话、摘要、消息;
  • 2)消息同步:推、拉;
  • 3)消息通道:长连接、厂商推送。

与一般IM会话模型不同的是,闲鱼会话以商品为主体,“人+人+商品”为要素构建会话。

因会话模型的差异,淘系已有的消息系统,短期内无法满足业务需求,而闲鱼完全自建消息系统耗时巨大。

为了保障业务高效上线,技术选型上最大化复用已有系统能力,避免重复造轮子。

所以,我们的技术方案是:

  • 1)数据模型与底层存储依赖淘系私信体系进行建设;
  • 2)消息数据获取上,客户端全量从服务端拉取消息数据;
  • 3)通讯协议使用来往SDK及mtop。

总体架构如下图,以此模式完成快速交付保障了业务最小化可用:

4、2.0版:用户量增速快、需要重建消息系统

4.1 技术背景

闲鱼用户量正快速突破100万,即时消息服务的调用量暴涨。在这样的背景下,用户反馈消息数据获取的卡顿、白屏成为常态,大量的消息Push发送下,系统告警频发。

造成这些问题的原因:1.0版的架构模式下,获取消息数据全量拉模式,客户端纯UI不做数据存储。

具体就是:

  • 1)当用户需要查看消息数据时,数据拉取成功与否取决于网络、数据访问速度,偶发性的造成卡顿、白屏;
  • 2)中心化的数据存储,读远大于写,高并发下,服务端负载过大。

针对第2)点:比如1W个用户同时在线聊天,按照当前架构并发拉取全量消息,估算5万QPS。不妨假设,同时在线聊天用户数10万时,对服务端压力可想而知。

4.2 技术方案

基于上述问题,我们决定重建消息系统架构,以应对未来更大的用户增量。

回归到IM系统的核心功能:

4.2.1)消息存储模型:

  • 1)会话模型:由owner、itemid、user、sessionType 来标识唯一会话,增加扩展属性支持个性化;
  • 2)摘要模型:作为用户会话视图,同一会话的不同用户可个性化呈现,由userid、sid标识唯一摘要;
  • 3)消息模型:由sender、消息内容、消息版本、sid组成。sid+消息版本唯一确定一条消息;
  • 4)指令模型:是一种双端约定,由服务端下发,客户端执行的指令集。如免打扰指令、删除指令等。

4.2.2)消息通道:

1)在线通道:使用淘宝无线ACCS长连接提供的全双工、低延时、高安全的通道服务;

2)离线通道:使用淘宝消息推送平台AGOO. 其屏蔽了各主流厂商对接的复杂度,直接对业务系统提供服务。

4.2.3)消息同步模型:

1)客户端建立数据库,存储消息数据:当消息数据存储在本地设备上,消息同步从全量拉取优化为全量+增量同步结合的模式。

增量和全量同步具体指的是:

  • a. 增量同步:客户端存储消息位点信息,通过与服务端最新位点比较,仅同步增量消息;
  • b. 全量同步:当用户卸载重装或位点gap过大时,客户端全量拉取历史消息数据,进行端上数据重建。

2)服务端建设个人消息域环(收件箱模型):以和客户端进行增量数据同步。同时,1.0版本架构中存在的读多写少的问题,通过个人域环的写扩散来平衡读写压力。

下图为一条消息从发送到接收的过程以及服务端和客户端的执行流程:

如上图所示:假设Ua给Ub发送一条消息,消息写扩散至Ua和Ub的各自的域环中:

  • 1)当客户端online时,接收到推送的消息位点=当前端上域版本+1,本地消息数据库merge即可;
  • 2)当客户端offline时,仅进行离线推送通知,当用户重新上线时,进行数据同步,由服务端判断触发增量同步还是全量同步。

针对第2)点,具体逻辑是:

  • 1)如果域环版本差值小于阀值,增量同步后,进行本地消息数据库merge;
  • 2)当域环版本差值大于阀值,进行全量消息拉取,做端上数据重建。

整个同步逻辑基于闲鱼的即时消息域环,域环可以看作是有着固定容量的用户消息收件箱,给一个用户发送的所有消息都会同步到他的域环中。

具体就是:

  • 1)域环存储:域环需要支持高并发数据读写,使用阿里分布式KV存储系统tair来实现;
  • 2)域环容量:为减少全量消息同步,以用户下次进入闲鱼需要同步的平均消息量来规划个人域环容量。同时利用FIFO循环覆盖历史数据;
  • 3)域环版本:用户当前消息位点,在消息进入个人域环时通过tair的counter实现域环版本严格连续递增,用于全量、增量同步判断。

上述建设完成后,闲鱼具备了自己独立的即时消息系统,当下遇到的问题得到了缓解,用户体验度有大幅提升。

5、3.0版:随着业务快速发展,系统稳定性需得到保障

5.1 技术背景

随着闲鱼业务生态的丰富,IM会话与消息内容类型不断扩展,同时在用户量的快速增长下,用户反馈消息收不到、消息延迟等舆情问题日渐突出。

5.2 问题分析

问题1:闲鱼app进程无有效保活机制,app退到后台后进程很快就会被系统挂起,导致长连接中断。此时消息推送走厂商通道,而厂商通道的实时性较差,且对消息推送的优先级设定有差异,从而造成用户感知消息延迟。

问题2:accs在线消息推送时,平均延时较短,但存在假连情况。而且目前的消息推送链路无ack机制,造成服务端以为消息发出去了但实际上客户端并没有收到,用户下次打开app后才能看到消息,用户感知消息延迟。

PS:造成假连接的原因主要是用户退到后台,accs长连中断,但是设备状态更新有延时。

问题3:目前消息同步的推模式(accs push)、拉模式(mtop),客户端未做隔离,异步进行处理,导致在某些极端情况下消息数据库处理异常,引发消息丢失。

如:某用户上线后连续收到多条消息,其中一条触发域黑洞,在进行消息同步端上数据重建时,小概率处理出错。

问题4:大部分线上消息问题发现靠舆情反馈,如消息错乱,出问题后系统无感知、无补救措施且排查困难,仅能跟随版本做修复。

问题5:业务不断丰富,孵化出基于消息系统的服务号及小程序内容营销、消息群组等,各类消息发送链路共用域环与数据存储,造成稳定性问题。

如:个人域环的消息包括IM聊天和营销消息,IM聊天由用户触发,需要保证强到达;而营销消息一般是由系统通过班车等方式批量发送,消息量级大,tps高,影响IM服务稳定性。

5.3 解案决方案

基于上述分析,我们逐个问题进行专项解决。

1)消息重发与推拉隔离:

如上图所示:

  • a. ACK:保障消息及时到达。服务端下行accs消息时,将消息加入重试队列并延迟重试,客户端在收到accs消息并处理成功后,给服务端回一个ack,服务端收到ack后更新消息到达状态,并终止重试,以此避免设备假连或网络不稳定的情况;
  • b. 重发:根据延迟重发策略决定何时重发消息,保障消息确定性到达。自适应延迟重发策略是指新消息先通过4次固定N秒的短延迟来探测设备的网络状况,然后根据网络状况来递增固定步长M的延迟策略,这种策略可以保障在最短的时间内,使用最少的重发次数将消息投递成功;
  • c. 消息队列:端上引入消息队列,按顺序处理消息,保证消息处理的准确性。同时进行推拉隔离,保障队列有序消费,解决了复杂状况下并发处理消息数据合并出错的问题。

2)数据存储拆分:

闲鱼每天发送的即时消息中有一半以上是营销消息,营销消息的发送具有明显的波峰波谷流量,高峰期会导致消息数据库抖动,影响IM消息。我来对消息、摘要、域环存储做业务隔离,以适应不同业务场景对稳定性不同的要求。

具体做法是:

  • 1)IM消息需要极高的稳定性保证,其消息及摘要继续使用mysql存储;
  • 2)营销消息存储周期短,稳定性要求低于IM,采用Lindorm存储;
  • 3)域环做实例级别隔离,保证IM域环的容量不会被其他消息占用,从而影响到消息同步。

PS:Lindorm是一种多模型的云原生数据库服务,具有成本低、自定义TTL、容量横向扩展等优势。

3)线上问题发现与恢复:

保障稳定性的关键要素是做好各种核心指标的监控,而监控首先要有数据来源,对服务端+客户端的关键链路节点埋点,基于集团UT、SLS,通过blink进行实时清洗、计算,最终形成统一规范的日志数据落至SLS,以供实时监控及链路排查。

消息系统的核心目标是保障用户消息发的出、收得到且及时收到,所以我们通过计算发送成功率、到达率、消息延迟来监控系统的稳定性。

此外,为了解决用户舆情排查困难的问题:

  • 1)我们设计了一套指令集,通过约定指令协议,服务端向指定用户下发指令,客户端执行对应指令进行异常数据上报,提高排查效率;
  • 2)扩展了强制全量同步、数据校正等指令,定向修复用户消息数据问题,相较以往出现严重bug只能让用户卸载重装解决,这种方式显然对用户是更友好的。

经过一系列专项治理,技术类舆情下降50%,从0到1建设了消息稳定性体系,用户体验进一步提升。

6、展望未来

闲鱼作为电商交易APP, 其中IM是交易的前置链路,IM的产品体验极大影响用户交易效率。

前段时间进行用户调研,从闲鱼IM的NPS低于预期(NPS是用户忠诚度衡量指标 = 推荐者%-贬损者%)。

从用户反馈来看:

  • 1)部分用户对产品功能有较强烈的诉求,诸如消息搜索、分组等;
  • 2)大部分用户对发送消息过程中的违规问题难以理解;
  • 3)仍有较多舆情反馈消息收不到或延迟。

映射到目前闲鱼的即时消息系统上,我们的系统架构依然有很多需要持续改进的地方。

典型的如:同步协议冗余,在需求迭代过程中容易引发问题、有效保活机制的缺失对消息即时送达的影响、小众机型离线消息收不到、多年的数据积累在线库臃肿等问题,影响着闲鱼业务迭代速度与NPS。

作为技术团队,下一步将提升NPS作为核心技术目标,闲鱼的即时消息系统4.0版架构正在路上 ......

附录:更多相关文章

[1] 更多阿里巴巴的技术资源:

阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处

现代IM系统中聊天消息的同步和存储方案探讨

阿里技术分享:深度揭秘阿里数据库技术方案的10年变迁史

阿里技术分享:阿里自研金融级数据库OceanBase的艰辛成长之路

来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享

钉钉——基于IM技术的新一代企业OA平台的技术挑战(视频+PPT) [附件下载]

阿里技术结晶:《阿里巴巴Java开发手册(规约)-华山版》[附件下载]

重磅发布:《阿里巴巴Android开发手册(规约)》[附件下载]

作者谈《阿里巴巴Java开发手册(规约)》背后的故事

《阿里巴巴Android开发手册(规约)》背后的故事

干了这碗鸡汤:从理发店小弟到阿里P10技术大牛

揭秘阿里、腾讯、华为、百度的职级和薪酬体系

淘宝技术分享:手淘亿级移动端接入层网关的技术演进之路

难得干货,揭秘支付宝的2维码扫码技术优化实践之路

淘宝直播技术干货:高清、低延时的实时视频直播技术解密

阿里技术分享:电商IM消息平台,在群聊、直播场景下的技术实践

阿里技术分享:闲鱼IM基于Flutter的移动端跨端改造实践

阿里IM技术分享(三):闲鱼亿级IM消息系统的架构演进之路

 

[2] 有关IM架构设计的文章:

浅谈IM系统的架构设计

简述移动端IM开发的那些坑:架构设计、通信协议和客户端

一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

一套原创分布式即时通讯(IM)系统理论架构方案

从零到卓越:京东客服即时通讯系统的技术架构演进历程

蘑菇街即时通讯/IM服务器开发之架构选择

腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT

微信后台基于时间序的海量数据冷热分级架构设计实践

微信技术总监谈架构:微信之道——大道至简(演讲全文)

如何解读《微信技术总监谈架构:微信之道——大道至简》

快速裂变:见证微信强大后台架构从0到1的演进历程(一)

移动端IM中大规模群消息的推送如何保证效率、实时性?

现代IM系统中聊天消息的同步和存储方案探讨

微信朋友圈千亿访问量背后的技术挑战和实践总结

子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

社交软件红包技术解密(一):全面解密QQ红包技术方案——架构、技术实现等

从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路

从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实践总结

从游击队到正规军(三):基于Go的马蜂窝旅游网分布式IM系统技术实践

瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)

IM开发基础知识补课(九):想开发IM集群?先搞懂什么是RPC!

阿里技术分享:电商IM消息平台,在群聊、直播场景下的技术实践

一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等

一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等

从新手到专家:如何设计一套亿级消息量的分布式IM系统

企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等

融云技术分享:全面揭秘亿级IM消息的可靠投递机制

IM开发技术学习:揭秘微信朋友圈这种信息推流背后的系统设计

阿里IM技术分享(三):闲鱼亿级IM消息系统的架构演进之路

>> 更多同类文章 ……

本文已同步发布于“即时通讯技术圈”公众号。

同步发布链接是:http://www.52im.net/thread-3699-1-1.html 

posted @ 2021-09-13 15:12 Jack Jiang 阅读(345) | 评论 (0)编辑 收藏

     摘要: 本文引用自“ 豆米博客”的《JS实时通信三把斧》系列文章,有优化和改动。1、引言有关Web端即时通讯技术的文章我已整理过很多篇,阅读过的读者可能都很熟悉,早期的Web端即时通讯方案,受限于Web客户端的技术限制,想实现真正的“即时”通信,难度相当大。传统的Web端即时通讯技术从短轮询到长连询,再到Comet技术,在如此原始的HTML标准之下,为了实现...  阅读全文

posted @ 2021-09-07 10:47 Jack Jiang 阅读(215) | 评论 (0)编辑 收藏

本文由融云技术团队原创分享,原题“技术实践丨万人群聊的消息分发控速方案”,为使文章更好理解,内容有修订。

1、引言

传统意义上的IM群聊,通常都是像微信这样的500人群,或者QQ的2000人群(QQ有3000人群,但那是单独收费的,也就意味着它并非无门槛标配,能用上的人并不多)。

自从国外某号称“世界上最安全的IM”搞出万人群聊之后,万人群迅速被国内的使用者们接受。伴随着移动互联网的发展,即时通讯服务被广泛应用于各个行业(以经不再局限于传统IM社交应用领域),随着业务快速发展,传统百人、千人上限的群聊已经无法满足很多业务场景需求,所以万人甚至十万人的超大群也算是相伴而生、顺应潮流。 

▲ “纸飞机”的万人群(开发人员颤抖中...)

IM群聊一直是IM应用中比较有难度的热点技术之一,通常意义的群聊,无非就是500人群、1000人群、2000人群这样,技术实现上比单聊要复杂不少。然而对于万人群聊(甚至十万人群聊)来说,相比百人、千人群聊,技术实现上那几乎是另一个技术维度的事情,难度要高很多。

本文根据融云技术团队的实践经验,总结了万人群聊消息投递方案的一些思考和实践,希望能给你带来启发。

学习交流:

- 即时通讯/推送技术开发交流5群:215477170 [推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK

(本文同步发布于:http://www.52im.net/thread-3687-1-1.html

2、相关文章

万人群聊有关的技术文章还可读一读以下这篇:

  1. 网易云信技术分享:IM中的万人群聊技术方案实践总结
  2. 企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等
  3. 阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处

融云技术团队分享的其它文章:

  1. 融云技术分享:融云安卓端IM产品的网络链路保活技术实践
  2. 融云技术分享:全面揭秘亿级IM消息的可靠投递机制
  3. 融云技术分享:基于WebRTC的实时音视频首帧显示时间优化实践
  4. IM消息ID技术专题(三):解密融云IM产品的聊天消息ID生成策略

3、超大群面临的技术挑战

与百人群、千人群相比,万人、甚至十万人超大群,大幅提升了群的触达人数,对于很多业务场景来说,好处不言而喻。

然而单群成员如此之大,给 IM 系统的流量冲击非常巨大,技术难度可想而之。我们先来分析一下超大群的技术挑战。

以一个万人群的模型为例:

  • 1)如果群中有人发了消息,那么这条消息需要按照 1:9999 的比例进行分发投递,如果我们按照常规消息的处理流程,那么消息处理服务压力巨大;
  • 2)消息量大的情况下,服务端向客户端直推消息的处理速度将会成为系统瓶颈,而一旦用户的消息下发队列造成了挤压,会影响到正常的消息分发,也会导致服务缓存使用量激增;
  • 3)在微服务架构中,服务以及存储(DB,缓存)之间的 QPS 和网络流量也会急剧增高;
  • 4)以群为单位的消息缓存,内存和存储开销较大(消息体的存储被放大了万倍)。

基于这些技术挑战,要想真正达成超大群的技术目标,势必要做特定的技术优化来应对。

4、一般群聊的消息投递模型

先来看看普通群聊的消息投递模型。

我们的普通群聊消息投递模型如下图所示:

如上图所示,当用户在普通群里发了一条消息后,投递路径是:

  • 1)消息先到群组服务;
  • 2)然后通过群组服务缓存的群关系,锁定这条消息最终需要分发的目标用户;
  • 3)再根据一定的策略分发到消息服务上;
  • 4)消息服务再根据用户的在线状态和消息状态来判断这条消息是直推、通知拉取还是转 Push,最终投递给目标用户。

普通群聊的消息投递,正像您期待的那样,基本上大家的实现手段都大差不差。然而对于万人群来说,这显然还不够。

下面来看看我们针对万人群聊消息投递的技术优化手段。

5、万人群聊消息投递优化手段1:控速

针对万人群的消息投递,我们的一个主要手段就是控速。

如上图所示。

首先:我们会根据服务器的核数来建立多个群消息分发队列,这些队列我们设置了不同的休眠时间以及不同的消费线程数。

通俗来讲,可以将队列这样划分为快、中、慢等队列。

其次:我们根据群成员数量的大小来将所有群映射到相应的队列中。

规则是:

  • 1)小群映射到快队列中;
  • 2)大群映射到相应的慢队列中。

然后:小群由于人数少,对服务的影响很小,所以服务利用快队列快速的将群消息分发出去,而大群群消息则利用慢队列的相对高延时来起到控速的作用。

6、万人群聊消息投递优化手段2:合并

在本文第3节中提到的万人群聊所面临的技术挑战,最主要的挑战其实就是消息进行扩散分发投递后,消息被克隆出N条,消息流量瞬间被放大。

举个例子:当一条群消息发送到 IM 服务器后,需要从群组服务投递给消息服务,如果每一个群成员都投递一次,并且投递的群消息内容是一致的话,那肯定会造成相应的资源浪费和服务压力。

那么针对这种情况,我们的解决方案就是进行消息合并投递。

原理就是:服务落点计算中我们使用的是一致性哈希,群成员落点相对固定,所以落点一致的群成员我们可以合并成一次请求进行投递,这样就大幅提高了投递效率同时减少了服务的压力。

下图是云信团队分享的万人群消息合并投递逻辑:

▲ 上图引用自《IM中的万人群聊技术方案实践总结

如上图所示,云信团队的万人群消息合并投递方案是:按Link分组路由消息,同一Link上的全部群成员只需要路由一条消息即可。

7、十万、百万级的超大群处理方案

在实际群聊业务中,还有一种业务场景是超大规模群,这种群的群人数达到了数十万甚至上百万。

这种群如果按照上述的投投递方案,势必仍会造成消息节点的巨大压力。

比如我们有一个十万人的群,消息节点五台,消息服务处理消息的上限是一秒钟 4000 条,那每台消息节点大约会分到 2 万条群消息,这已大大超出了消息节点的处理能力。

所以为了避免上述问题,我们会将群成员上线超过3000的群识别为万人群、超级群,这种级别的群可以根据服务器数量和服务器配置相应做调整针对这种超级群会用特殊的队列来处理群消息的投递。

这个特殊的队列1秒钟往后端消息服务投递的消息数是消息服务处理上限的一半(留相应的能力处理其他消息),如果单台消息服务处理的 QPS 上限是 4000,那群组服务一秒往单台消息服务最多投递 2000 条。

8、写在最后

未来,我们也会针对群消息进行引用投递,对于大群里发的消息体比较大的消息,我们给群成员只分发和缓存消息的索引,比如 MessageID。等群成员真正拉取群消息时再从将消息组装好给客户端分发下去。这样做会节省分发的流量以及存储的空间。

随着互联网的发展,群组业务的模型和压力也在不停地扩展,后续可能还会遇到更多的挑战,当然也会不断迭代出更优的处理方式来应对。

附录:更多IM群聊技术文章

快速裂变:见证微信强大后台架构从0到1的演进历程(一)

如何保证IM实时消息的“时序性”与“一致性”?

IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?

IM群聊消息如此复杂,如何保证不丢不重?

微信后台团队:微信后台异步消息队列的优化升级实践分享

移动端IM中大规模群消息的推送如何保证效率、实时性?

现代IM系统中聊天消息的同步和存储方案探讨

关于IM即时通讯群聊消息的乱序问题讨论

IM群聊消息的已读回执功能该怎么实现?

IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?

一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

[技术脑洞] 如果把14亿中国人拉到一个微信群里技术上能实现吗?

IM群聊机制,除了循环去发消息还有什么方式?如何优化?

网易云信技术分享:IM中的万人群聊技术方案实践总结

阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处

IM群聊消息的已读未读功能在存储空间方面的实现思路探讨

直播系统聊天技术(一):百万在线的美拍直播弹幕系统的实时推送技术实践之路

直播系统聊天技术(二):阿里电商IM消息平台,在群聊、直播场景下的技术实践

直播系统聊天技术(三):微信直播聊天室单房间1500万在线的消息架构演进之路

直播系统聊天技术(四):百度直播的海量用户实时消息系统架构演进实践

企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等

融云IM技术分享:万人群聊消息投递方案的思考和实践

>> 更多同类文章 ……

本文已同步发布于“即时通讯技术圈”公众号。

同步发布链接是:http://www.52im.net/thread-3687-1-1.html

posted @ 2021-08-30 11:34 Jack Jiang 阅读(229) | 评论 (0)编辑 收藏

     摘要: 本文由微医云技术团队前端工程师张宇航分享,原题“从0到1打造一个 WebRTC 应用”,有修订和改动。1、引言去年初,突如其来的新冠肺炎疫情让线下就医渠道几乎被切断,在此背景下,在线问诊模式快速解决了大量急需就医病患的燃眉之急。而作为在线问诊中重要的一环——医患之间的视频问诊正是应用了实时音视频技术才得以实现。众所周之,实时音视频聊天技术门槛很高,一...  阅读全文

posted @ 2021-08-24 12:24 Jack Jiang 阅读(339) | 评论 (0)编辑 收藏

仅列出标题
共54页: First 上一页 25 26 27 28 29 30 31 32 33 下一页 Last 
Jack Jiang的 Mail: jb2011@163.com, 联系QQ: 413980957, 微信: hellojackjiang