背景

随着用户数的快速增长,闲鱼的IM也迎来了前所未有的挑战。多年的业务迭代,端侧IM的代码已经因为多年的迭代层次结构不足够清晰,之前消息一些隐藏起来的数据同步问题,也随着用户数的增大而被放大。

这里面的具体流程在于,后台需要同步到用户端侧的数据包,后台会根据数据包的业务类型划分成不同的数据域,数据包在对应域里面存在唯一且连续的编号,每一个数据包发送到端侧并且被成功消费后,端侧会记录当前每一个数据域已经同步过的版本编号,下一次数据同步就以本地数据域的编号开始,不断的同步到客户端。

当然用户不会一直在线等待消息,所以之前这里端侧采用了推拉结合的方式保证数据的同步。

  • 在线时使用ACCS实时的将最新的数据内容推送到客户端。ACCS是淘宝无线向开发者提供全双工、低延时、高安全的通道服务。

  • 离线启动后,根据本地的数据域编号,拉取不在线时候的数据差。

  • 当数据获取出现黑洞(数据包Version不连续的状态)时,触发数据同步拉取。

分析

现存的一个同步策略是可以基本保障IM的数据同步的,但是也伴随着一些隐含的问题:

  1. 短时间密集数据推送时,会快速的触发多次数据域同步。域同步回来的数据如果存在问题,又会触发新一轮的同步,造成网络资源的浪费。冗余数据包/无效的数据内容会占用有效内容的处理资源,又对CPU和内存资源造成浪费。

  2. 数据域中的数据包客户端是否正常消费,服务端侧无感知,只能被动地根据当前数据域信息返回数据。

  3. 数据收取/消息数据体解析/存储落库逻辑拆分不够清晰,无法针对性的对某一层的代码拆分替换进行ABTest。

针对遇见的这些问题,对闲鱼IM进行分层改造,抽离数据同步层。除了希望以后这个数据的同步内容可以用在IM之外,也希望随着稳定性的增加,赋能其他的业务场景。

本文重点来看下端侧闲鱼IM数据同步的一些解决思路。

数据同步优化

拆分&分层

对于服务端来说,业务侧产出数据包后,会拼接上当前的数据域信息,然后通过数据同步层将数据推送到端侧。

对于客户端来说,接收到数据包后,会根据当前的数据域信息,来确定需要消费数据包的业务方,确保数据包在数据域内完整连续后,将数据体脱壳后交于业务侧消费,并且应答消费的状况。

数据同步层的抽取,把数据同步中的加壳、脱壳、校验,重试流程封装到一起,可以让上层业务只需要关心自己需要监听的数据域信息,然后当这些数据域更新数据的时候,可以获取到这些数据进行消费,而不再需要关心数据包是否完整。

业务侧只需要关心业务侧对接的协议,数据侧只需要关心数据侧包装的协议,网络层负责真实的数据传输。

  1. 对齐数据层数据传输协议、描述当前数据包体数据域信息

  2. 将消息的处理/合并/落库抽离成数据消费者

  3. 上下楼依赖抽象化,去除对于具体实现的依赖

数据层结构模型

基于对于数据模型剥离和对当下遇见的问题的解决方案规整,将数据同步层拆分为这样的架构:

step1:App启动时建立ACCS长链接服务,保证推推送信道链接,并且根据当前本地数据域信息触发一次数据拉取。

step2:数据消费者注册消费者信息和需要监听的数据域信息,这里是一对多的关系。

step3:新的数据抵达端侧后,将数据包放到指定的数据域的缓冲池,批量数据归纳结束后,重新出发数据的读取。

step4:根据当前数据域优先级弹出最高优的数据包,判断数据域版本是否符合消费者要求,符合则将数据包脱壳后丢给消费者消费,不符合则根据上一次正确的数据包的域信息触发增量的数据域同步拉取。

step5:触发数据域同步拉取时,block数据读取,此时通过ACCS触达的数据依旧会在继续归纳到指定的数据域队列中,等待数据域同步拉取结果,将数据包进行排序、去重,合并到对应的数据域队列中。然后重新激活数据读取。

step6:数据包体被消费者正确消费后,更新域信息并且通过上行信道告知服务端已经正确处理的数据域信息。

数据域同步协议

Region中携带的数据不必过多,但是又需要将数据包的内容描述清楚

  • 目标用户的ID,用以确定目标数据包是否正确

  • 数据域ID和优先级信息

  • 当前数据包的域优先级版本

排序策略

针对于域数据归纳,无论是在写入数据的时候进行排序还是在读取的时候进行查找都需要进行一次排序的操作,时间复杂度最优也是O(logn)级别的,在实际coding中发现由于在一个数据域里面,数据包的Version信息是连续唯一并且不存在断层的,上一个稳定消费的数据体的Version信息自增就是下一个数据包的Version,所以这里采用了以Versio为主键的Map存储,既降低了时间复杂度,也使得唯一标识的数据包后抵达端侧的包内容可以覆盖之前的包内容。

一些问题&解决策略

多数据来源和唯一数据消费的平衡

每当产生一条针对于当前用户的数据包,如果当前ACCS长链接存在,就会通过ACCS将数据包推送到客户端,如果App切换到后台一段时间,或者直接被杀死,ACCS链接断开,那么只能通过离线推送到用户的通知面板。所以每当App切换到活跃状态,都需要根据当前本地存储的数据域信息从后台触发一次数据同步

数据包触达到端侧的来源主要是ACCS长链接的推送和域同步时的拉取,但是数据包的消费是根据数据域的监听划分的唯一消费者,也就是同一时间内只能消费一个数据包。

在压力测试中,当后台短时间内密集的将数据包通过ACCS推送到端侧时,端侧接收到的数据包并不有序,不连续的数据包域版本又会触发新的数据域同步,导致同样的一份数据包会通过两个不同的渠道多次的触达到端侧,浪费了不必要的流量。

当数据域同步时,这个时间节点产生的新数据包也会推送到端侧,数据体有效,并且需要被正确的消费。

针对这些问题的解决策略:

在数据消费和数据获取中间装载一个数据中间层,当触发数据域同步的时候block数据的读取并且ACCS推送下来的数据包会被存放在一个数据的中转站里面,当数据域同步拉取的数据回来后,对数据进行合并后再重启数据读取流程。

数据域优先级

需要推送到端侧的数据包,根据业务的不同优先级也有不同的划分,用户和用户的聊天产生的数据包会比运营类的消息的数据包优先级要高一些,所以要当多优先级的数据包快速的抵达端侧时,高优先级数据域的数据包需要被优先消费,而数据域的优先级也是需要动态调整,不断变换的优先级策略。

针对这个问题的解决策略:

不同的数据域,产生不同的数据队列,高优队列里面的数据包会被优先读取消费。

每一个数据包体中带回的数据域信息,都可以标注当前的数据域优先级,当数据域优先级发生变化的时候,调整数据包消费优先级策略。

优化效果

除去结构上分层梳理,使得数据同步层和依赖的服务内容可便捷解耦/每一个环节可插拔之外,数据同步中对于消息消费时长/流量节省,压力测试场景下优化效果更加明显。

压力测试场景:500ms内100条全乱序数据包推送

消息处理时长(接收-上屏)缩短 31%

流量损耗(最终拉取到端侧数据包累积大小)降低35%

后续计划

数据同步层能力提升

数据同步侧的目标,既要保证数据包完整的到达端侧,又要在保证稳定性的前提下尽可能的减少数据的拉取,使得每一次数据的获取都有效。后续数据同步层会着手于有效数据率和到达率进行更进一步的优化。

  • 针对不同的场景,动态智能调整数据同步的优先级策略。

  • 阻塞式长链接推送,保证同一时间只存在推模式或者拉模式,进一步减少冗余数据包的推送。

闲鱼IM端侧整体架构升级

升级数据同步层策略主要还是要提升闲鱼IM的能力,将数据同步分层后,接下来就是将消息的处理流程化,对每一个流程都可监控可回溯,提升IM数据包的正确解析存储和落库率。

  • 在数据来源侧剥离开后,后续对IM的整改也会逐步的将消息的处理分层剥离

  • 消息处理关键节点的流程式上报、建立完整的监控体系,让问题发现先于用户舆情

  • 消息完整性的动态自检,最小化数据补偿补全。

注: 该改造升级将于十一月中旬的版本和大家见面,敬请期待

如何有效缩短闲鱼消息处理时长相关推荐

  1. 闲鱼下单时显示服务器繁忙,闲鱼翻车记。闲鱼用验机报告需要注意的问题,否则分分钟被水鱼...

    闲鱼翻车记.闲鱼用验机报告需要注意的问题,否则分分钟被水鱼 2019-10-03 21:35:34 62点赞 75收藏 163评论 本文主要想说的:闲鱼验机报告觉得不合适,一定要拒绝本次交易.对自己有 ...

  2. java 统计在线时长_如何有效统计app用户在线时长?

    Android平台: sdk版本v5.2.0及之后: app的单次使用时长=本次启动的结束时间减去本次启动的开始时间,即end_time减去start_time. 如果在本次启动过程中,应用退到后台运 ...

  3. 收藏!闲鱼卖货实操,小白轻松入门

    闲鱼是什么?是依附于淘宝的一个二手交易平台,拥有着淘宝巨大的流量倾斜,在过去的2019年火热项目除了短视频,还有就是闲鱼. 再加上2020年是特殊的一年,人人都想要参与进来分一杯羹,但经营一段时间后, ...

  4. 程序员副业之无货源闲鱼

    我将从以下这些方面来介绍闲鱼副业. 1.  闲鱼平台能不能挣钱? 2.  闲鱼平台都有哪几种挣钱方式? 3.  小白在闲鱼上怎么挣钱? 4.  能挣多少? 5.  如何养号? 6.  得到高权重的账号 ...

  5. 他把闲鱼APP长列表流畅度翻了倍(良心教程)

    简介:从"麻绳版顺滑"到"丝般顺滑" 作者:闲鱼技术-云从 1 整体思路 闲鱼在业务的快速迭代过程中,app 的长列表滑动流畅度逐步恶化,对用户浏览内容体验产生 ...

  6. php性能提升5倍的秘诀,停机维护时长缩短5倍,全靠这3个秘诀

    <停机维护时长缩短5倍,全靠这3个秘诀>要点: 本文介绍了停机维护时长缩短5倍,全靠这3个秘诀,希望对您有用.如果有疑问,可以联系我们.作者:朱志武 腾讯游戏高级运维工程师,腾讯学院讲师. ...

  7. TypeScript 3.9 正式发布!平均编译时长从 26 秒缩短至 10 秒

    作者 | 微软官方博客 译者 | 核子可乐 策划 | 小智 稿源 | 前端之巅 今天,微软在其官方博客宣布:TypeScript 3.9 版本已经正式发布,详情见下文. 有些朋友可能对 TypeScr ...

  8. 视频时间太长,怎样快速剪辑缩短视频的时长

    在制作视频时,难免会遇到一些剪辑问题,比如如何批量将多个视频的播放时长缩短等等.下面小编为大家介绍两种方法 原视频效果: 将需要剪辑的视频都存放在同一文件夹上 双击原视频查看,该视频的播放时长较长,可 ...

  9. 闲鱼如何在2个月内实现Android启动速度翻倍的?

    简介:满满干货 作者: 海潴,锦逸 随着闲鱼App端更多新功能.新技术的加入,应用冷启动速度越来越慢,这也意味着用户看到有效内容的时间被拉长,对用户体验有着很大的伤害.目前,在内部测试版本中,我们已经 ...

最新文章

  1. 院士戴琼海:脑科学走向人工智能的重要路径
  2. 深入理解mybatis原理, Mybatis初始化SqlSessionFactory机制详解(转)
  3. abaqus失效单元删除_abaqus单元删除的一般方法
  4. Web API Filter ActionFilterAttribute 使用
  5. 20172310《程序设计与数据结构》(上)课程总结
  6. python文件夹中的__init__.py的作用
  7. 将vue项目打包部署到云服务器(傻瓜式宝塔面板)
  8. 集成CCFlow工作流与GPM的办公系统驰骋CCOA介绍(二)
  9. Modem Device on High Definition Audio Bus
  10. 案例十三、模仿微信打飞机游戏
  11. 手机QQ垃圾文件清理。
  12. fopen()函数的整理
  13. java大小写敏感_Java是大小写敏感的语言。
  14. 使用 Web3.js 连接以太坊节点并查询区块链数据
  15. 解剖Twitter:Twitter系统架构设计分析
  16. 亚稳态与信号跨时钟域介绍
  17. 如何分辨on-policy和off-policy
  18. java项目-第153期ssm超市进销存管理系统-ssm毕业设计-计算机毕业设计
  19. deepin更新失败_Deepin深度应用商店和系统更新不正常的解决方法
  20. 『yeka』打开心灵——SD2.0大会更显大家风范

热门文章

  1. C++面向对象三大特性——封装与信息隐蔽
  2. 对JavaScript事件循环机制的理解
  3. 华为OD真题:学习成长记录篇:深度优先搜索算法+递归思想
  4. MySQL5.7.19 服务挂掉 自动关闭 mysqld got exception 0xc000001d win 2008R2
  5. Windows 2008 R2上MySQL5.7异常关闭,报错:mysqld got exception 0xc000001d问题解决
  6. 如何快速提取大量文件名到excel?
  7. SQL 添加约束关键字
  8. html5用代码实现页面跳转页面跳转,H5上滑跳转页面的实现(代码实例)
  9. mysql 日期小于当前日期_如何使用MySQL选择小于当前日期的日期?
  10. 不用注册NVIDIA账号直接下载cuDNN的方法之使用迅雷下载到的是index.html问题解决