向消息延迟说bybye:闲鱼消息及时到达方案(详细)

背景

IM消息作为闲鱼用户重要的交易咨询工具,核心目标有两点,第一是保证用户的消息不丢失,第二是保证用户的消息及时送达接收方。IM消息根据消息的接收方设备是否在线,分为离线和在线推送,数据显示目前闲鱼每天有超过一半以上的IM消息是走在线通道的,而在线消息的到达率、及时性是直接影响用户体验的,本文将着重分析优化在线通道的稳定性,保证用户消息及时到达。

面临哪些问题

端内长连接中断

在IM场景中,用户与云端通信频繁,且为了实现用户的消息及时到达,往往采用云端下推消息的方式触达用户,所以用户在线时设备与云端会维持一条TCP长连接通道,可以更轻量级的与服务端进行交互,现代IM即时通讯的下行消息都是通过长连下发的,闲鱼消息使用的是ACCS长连接,ACCS是淘宝无线提供的全双工、低延时、高安全的通道服务。但是由于用户设备网络状态的不确定性,可能会发生各种各样的网络异常情况导致长连接通道中断,长连接一旦意外中断,就会导致用户无法及时收到在线消息,所以我们需要尽可能及时的感知到长连中断并尝试重连。

下推的消息未达

感知长连中断并重连只能在大多数时间保证长连接的有效性,但是在长连接无效或不稳定期间下推的消息客户端可能根本收不到,简单说就是仅仅有重连机制无法保证下行消息必达,可能有以下场景导致下行消息失败:

  • 服务端发送下行消息时长连畅通,消息在传输路上通道断掉,客户端无法收到 

  • 设备的在线状态存在延迟,服务端下行消息时认为设备在线,实际上设备已经离线,无法收到 

  • 客户端收到了下行消息,但端上后续处理失败,比如落库失败,消息没有成功展示给用户

我们通过数据埋点统计得出,accs下行成功率在97%左右

有心急的同学就要问了,丢了3%的消息吗?并没有,这3%的消息不会丢失,只是不保证及时触达给用户。我们的消息同步模型是推拉结合模式,在用户拉取消息时会拉取到设备当前位点与服务端最新位点的所有消息,accs下行失败的消息会通过主动拉模式获取到,但客户端主动拉取消息的触发时机有限,主要有以下几个:

  • 用户冷启动app,主动同步消息 

  • 用户主动下拉刷新 

  • app后台切换前台 

  • 收到一条推送消息,客户端发现新消息的位点跟本地最新的位点有gap,触发同步

可见上述主动同步消息的触发很大程度上依赖用户行为或者有没有收到新消息,难以保证消息及时到达。如果是用户高频打开的IM软件,这样也不会有太大的问题,但是闲鱼app的活跃度较低,有时候甚至依赖IM消息拉活,而且一条延迟的消息触达可能导致用户错过一笔交易,闲鱼消息不允许有这样的延迟发生。基于上述分析,我们先描述一个数据指标来反映现状,通过上面的描述可知,accs消息并不全都是推下来的,也可能是主动拉下来的,如果是推,必定可以及时到达,如果是拉,则受限于用户行为。拉的这部分消息,我们定义为accs消息补偿到达,然后计算accs消息补偿到达耗时,消息范围限定为服务端accs成功下行但是客户端通过主动拉取同步到的消息,以往的版本这个数据在60分钟左右。需要注意这个数据并不是消息触达到用户的耗时,因为如果在线转离线触达,拉取到消息的时间取决于用户行为(用户何时打开了app),但这个数据也能大致反映在线消息的到达延迟状况。

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

长连接重连

长连接为什么会中断?

百因必有果,我们先来分析下有哪些原因会导致连接中断,可能有以下原因: 

  • 用户设备断网 

  • 设备发生了网络切换 

  • 设备处于弱网环境,网络不稳定 

  • 设备网络正常,TCP连接由于NAT超时导致连接被运营商中断

如果是用户操作导致网络状态变化的情况,会有网络状态变化事件通知,这种情况可以监听事件并主动尝试重连,但现实中的大多数情况都是“意料之外”。那么如何有效感知到各种异常状况呢?

心跳检测

像大多数探活场景一样,最有效的检测手段就是心跳检测,客户端通过定时发送心跳包,可以感知到连接中断,从及时性效果来看,心跳间隔越短越好,而频繁的心跳检测势必会带来用户流量以及电量的损耗,所以我们的目标是如何尽可能少的心跳检测而又尽量及时地感知到长连中断的意外情况。

状态机+消息心跳队列:

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

心跳策略

心跳策略是实现我们上述目标的核心机制,但关于心跳策略的详细设计甚至可以单独写一篇文章,本文仅简单列举几种心跳策略,有兴趣的同学可以阅读文末推荐的文章继续深入研究。

  • 短心跳检测 初始状态连续 ping 3次 收到 ack 后,可以认为进入稳定状态

  • 常规固定时长心跳(根据app状态不同,频率可调Mid+,Mid-, Long)

  • 自适应心跳 根据设备网络状态变化自动适应的心跳间隔

  • 冗余心跳,app后台切前台,主动心跳一次

消息ack与重发

为了解决上面的问题,引入消息ack与重发机制,整体思路是客户端在收到accs消息并处理成功后,给服务端回一个ack,服务端下行accs消息时将消息加入重试队列,收到ack后更新消息到达状态,并终止重试。

整体设计流程图:

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

重试队列存储设计

我们采用阿里云表格存储TimeLine模型来存储下行消息的到达状态,阿里云表格存储是阿里云自研的多模型结构化数据存储,提供海量结构化数据存储以及快速的查询和分析服务。表格存储的分布式存储和强大的索引引擎能够支持PB级存储、千万TPS以及毫秒级延迟的服务能力。而Timeline 模型是针对消息数据场景所设计的数据模型,它能满足消息数据场景对消息保序、海量消息存储、实时同步的特殊需求,在IM、Feed流等消息场景应用广泛。

我们给每个用户设备定义一个TimeLine,timeline-id定义为userId_deviceId,sequenceId自定义为消息位点,存储结构如下: 

每通过accs成功下行一条消息,则插入到接收用户设备的TimeLine中,收到ack后根据消息id更新消息到达状态,同时由于重试动作只发生在下行消息后较短的一段时间内,所以我们设置一个比较短的全局过期时间即可,避免数据膨胀。

延迟重试设计

1)每通过accs下发一条消息,先插入到Timeline中,初始状态为未达,然后生产一条延迟N秒的延迟消息 

2)每次消费到延迟消息后,读取tablestore中该消息的到达状态,如到达则终止延迟,否则继续 

3)每次重试先判断设备是否在线,如果设备不在线,转发离线通道并终止重试,如果设备在线,则重推未到达的消息,并再次延迟N秒消费 

4)每条消息的重试生命周期中用的同一条延迟消息,最多重试消费M次,超过次数不再重试并打日志埋点,后续可以监控这种情况并基于这个数据进行优化

延迟重发策略

延迟重发策略是指在重发流程中,如何选择合适的延迟时间来使得重发的效率最高。不同用户在不同时间、地点所处的网络环境差别较大,网络恢复到稳定态所需要的时间也有差异,需要选用合适的延迟策略来保证重发效率,最优的延迟策略的目标是在最短的时间内,使用最少的重发次数将消息投递成功。

固定延迟时间

要想找到最优的延迟策略,必须从数据中通过分析得到答案,天马行空的想象往往离实际相差甚远,我们先采用固定的延迟时间(10s)最大重试6次来分析一波数据

我们通过这组数据可以看到,有约85%的消息在40s内重发可以投递成功,还有12%的消息在达到最大重试次数后依旧没有收到ack,在4次重试之后,第5次成功只有2.03%,第6次只有0.92%,继续重发的收益已经变得很低,6次以后还有部分消息没有收到ack,这部分消息如果用固定延迟时间策略,性价比很低,频繁重发浪费系统资源,我们继续改进策略。

固定延迟+固定步长递增

考虑到部分用户的网络短时间无法恢复,频繁的短间隔重发价值不大,我们采用4次固定短间隔延迟N秒后,之后每次延迟时间都是上一次延迟时间递增固定步长M秒的策略,直到收到ack、用户设备离线或者达到了最大延迟时间MAX(N)。这种策略一定程度上可以解决固定延迟时间重发策略的问题,但如果用户短时间网络无法恢复,每次重发都要重新递增,也不是一种最优解。

自适应延迟

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

新老版本兼容性

需要注意的是老版本的app是不会回ack的,如果下发给老版本设备的消息也加入重试队列,那此类消息将一直重试到最大次数才会终止,无端消耗资源,所以我们设计在accs长连建立之后,客户端主动上行一条设备信息,其中包含app的版本号,服务端存储一定时间,在将消息加入重试队列之前,先校验接收者设备app的版本号,符合要求再加入重试队列。

方案效果

消息重连重发方案上线后,我们上面定义的指标accs补偿到达时间从60分钟大幅降低至15分钟,降幅达75%,从而印证了我们的技术分析,同时用户有关消息延迟的舆情反馈每周不超过2个,可见消息重发机制对保证用户消息及时到达成效显著。

未来展望

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

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

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

References

[1] 现代IM系统中的消息系统架构 - 架构篇: https://developer.aliyun.com/article/698301
[2] 现代IM系统中的消息系统架构 - 模型篇: https://developer.aliyun.com/article/701593
[3] 高并发IM系统架构优化实践: https://developer.aliyun.com/article/66461

闲不住?来闲鱼!

PICK ME

闲鱼技术团队通过创新追寻更多价值,不断驱动业务变革。

从闲置生意的老本行,到打造“无忧购”“会玩社区““新线下”,

从出版书籍、峰会发声,到开源专利、海外传播,

闲不住,上闲鱼——技术团队对极致的探索与深耕是我们的底气。

 立即加入 

1、招客户端/服务端/前端/架构/质量工程师

2、发简历给guicai.gxy@alibaba-inc.com

3、您还可以在头条、知乎、掘金、facebook、twitter找到我们

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/56334.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java爬取闲鱼商品信息(一)

闲鱼真是一个很神奇的地方, 能让我等学生狗不用花很多钱就能体验科技的乐趣,当然,前提是别翻车。 好了,这当然是题外话,这阵子总结了自己学习的一些技能,就写一个对闲鱼的数据抓取来练练手。 预计达到的目…

网络爬虫淘宝api,获得淘宝app商品详情原数据

item_get_app-获得淘宝app商品详情原数据 注册测试 请求参数 请求参数:num_iid520813250866 参数说明:num_iid:淘宝商品ID 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)secretString是调用密钥api_nameStr…

闲鱼搜索相关性——体验与效率平衡的背后

背景 闲鱼搜索是闲鱼APP最大的成交场景入口, 成交归因中搜索占一半以上,所以提高成交效率是工程和算法迭代优化的主要目标,然而只以效率为最终的衡量标准不但会影响搜索的质量阻碍成交,还会恶化整个平台的长期生态建设无法成长&am…

闲鱼唤端的背后

背景 众所周知,想要DAU稳步上升,端外引流是一个必不可少的手段,常见的引流方式有:广告投放、分享回流、流量互换等,而他们也有着一个共同的技术问题,就是唤端,本文着重分享一下唤端的相关知识以…

闲鱼最新选品技巧,快速帮你找到爆款!

在星球里面,每天可以获得一些数据,主要是闲鱼热销品,稳定品类,还有一些三方的工具。 户外最近是个热品类,基本很多爆款都是从这里产生的,从前段时间分享的帐篷,板凳,烧烤架&#xff…

闲鱼商品理解数据分析平台——龙宫

引言 闲鱼是一个以C2C为主的平台,区别于B端的用户,C端卖家在发布商品时更倾向于图描述的轻发布模式,对于补充商品的结构化信息往往执行力和专业程度都不高,这为我们的商品理解带来了很大的困难。为了能够在发布侧获得更多的商品结…

闲鱼API接口,如何获取原生数据

闲鱼平台API,item_app 获得闲鱼原生数据 num_iid:闲鱼商品ID 点击获取key和secret* 当你有了账号时候点到测试页面,下面是我测试的结果 返回参数 Result Object: --------------------------------------- {"item": {"all_result&q…

闲鱼榜单数据

昨天有个客户给我看了这个页面,感觉挺有意思的:闲鱼榜单。 系统集成了各个行业,还推荐了用户可能感兴趣的行业的关键词,然后将行业内的卖家做一个排行。 比如潮玩行业的排名就是这样的: 然后就临时做了个接口&#xff…

闲鱼消息发展回顾

引言 闲鱼消息系统经过几代开发的建设,目前稳定的支撑亿级消息体量。在消息系统建设过程中,我们经历了从简单到复杂,从困扰到破局,每一次的技术改变都是为了更好的解决当下业务面临的问题。“忆昔午桥桥上饮,坐中多是豪…

电商搜索里都有啥?详解闲鱼搜索系统(长文)

搜索是电商平台的核心流量入口,承载着平台主要的成交引导、意图收敛、活动投放。一个稳定、高效、可扩展的搜索系统是电商平台得以生存发展的基石。本文探讨如何构建完善的商品搜索系统, 并根据闲鱼二手交易的差异化特性介绍闲鱼搜索系统的时效性优化。 …

闲鱼关键词,实现闲鱼APP的特定关键字商品检索

最近碰上个需求 需要根据关键词检索出所有商品,可以指定价格范围,地点,和最新排序,去发现有某位大佬的一个项目刚好符合这个需求。放到这里分享一下给大家。因为系统不便公开需要的可以找我 任务设置页面 可以设置关键词&#xf…

闲鱼商品选投实时性优化

马赫是闲鱼的选品和投放系统,闲鱼业务中多数商品都是孤品即单库存商品,所以商品的实时变更需要即刻反馈到选品和投放链路中,为了满足业务诉求马赫设计之初就把实时性作为最重要的技术目标,随着系统的运行数据的膨胀实时性也遇到了…

闲鱼已售商品信息查询系统。手搓市场定价/行情查询利器

前段时间自己手搓出来一个闲鱼已售商品查询接口,最近有时间,就把接口搞成了软件。 软件作用: 可以方便地查询闲鱼已经成交的商品信息,包括成交价格、成交时间、挂单后多少天成交(成交效率)、以及商品信息&a…

产品优化策略,有效提升产品自身竞争力,我赌你一定没用过

新媒体时代自移动互联网诞生之日便处于不断变化的事态之中,为了迎合时代发展要求,大数据、云计算等移动互联网技术获得了迅猛发展,智能手机也已经成为人们生活、工作中不可或缺的元素。在智能手机中,各种类型的APP占据了智能手机很…

2022届计算机毕业论文(设计)学生选题参考合集推荐收藏

大四的同学马上要开始毕业设计啦,大家做好准备了没! 给大家详细整理了计算机毕设最新选题,对选题有任何疑问,都可以问我哟~ 1基于JavaEE的问卷调查系统的设计与实现2基于SSM的山西工商学院校园跑腿代取系统的设计与实现3基于Web的…

计算机毕业论文选题推荐|软件工程|信息管理|数据分析|系列一

文章目录 导文题目导文 计算机毕业论文选题推荐|软件工程|信息管理 (***语言)==使用其他任何编程语言 例如:基于(***语言)门窗账务管理系统的设计与实现 得到:基于JAVA门窗账务管理系统的设计与实现 基于vue门窗账务管理系统的设计与实现 等等 题目 基于requests多线程…

湖北专升本数据结构

绪论 1.线性结构:是一一对应的关系。 2.集合结构:相当于一个班级,一个圈里面有很多。 3.“树”的数据结构:一对多的关系。 4.“图”的数据结构:多对多的关系。 名词解释 数据:是客观事实的符号表示,是所有能输入到计算机的符号的名称。 数据元素:…

英语四六级过了专升本可以加分吗?天津专升本英语四级加分取消

2021-2022年天津专升本考试中,全国大学英语四六级过了,那么天津专升本考试可以加分吗?天津专升本英语四级加分是不是与2020年取消了? 全国大学英语四、六级考试成绩的话题,又双叒叕登上了微博热搜 每到查分时&#xff…

专升本英语6套学习笔记和三套模拟试卷

第一部分 词汇背诵 1. literature [lit(ə)rətʃə] n. 文学;文献 I love literature since I was young. 从小我就热爱文学。 There is now a vast literature on the subject. 现在有关这个学科的文献特别多。 2. garment [gɑ:m(ə)nt] n. 衣服 The garm…