2、技术背景飞鸽是在抖音电商业务上面向商家和用户的聊天工具,其拉通售前、售中、售后渠道,为商家履约提供重要支撑。对于飞鸽桌面端IM而言,我们会面临很多基础挑战,比如做好会话稳定性、操作流畅性、冷启动速度等,而在满足98%以上的用户需求且业务趋于稳定后,一些在冲刺后遗留的性能天花板问题暴露在我们面前,其中高并发接待&多开是两个重要的挑战,是旧账与难啃的硬骨头。为何持续会有这些挑战存在?1)历史技术选型,包含者成本、人力、效率等考量,飞鸽客户端使用的技术栈是react+electron:*imsdk与业务渲染代码都由js编写,imsdk同时是cpu密集型&io密集型的组件,在高并发场景下,渲染频率也比较高,业务与sdk相互抢占cpu资源与io资源,导致收发消息慢、操作卡顿(高并发限制)。*由于imsdk运行在webview中,所以收发消息依赖webview存活,故多开账号=多个webview,内存成本线性增长。2)im页面在web层面多次优化后已接近架构上限,无法基于现有架构做更多天花板的突破。对于以上这些挑战,我们给出的解法是:对现有架构进行调整,使用Rust语言对imsdk进行重写,彻底解除这一块的性能瓶颈!
3、为什么选Rust语言?飞鸽imsdk是一个对运行稳定性要求高的组件,其工程量大、逻辑复杂,对于异步特性使用非常频繁,其对于内存安全、线程安全有着比较严格的要求。假如使用C++,作为新手并没有把握能够将复杂的IMSDK少bug的编写下来(团队限制)。Rust学习曲线虽然陡峭,但是其为安全设计的各类语言特性、强大的编译器,能够将新人编写代码的问题数降到最低(逻辑问题除外)。并且飞书团队提供了客户端的rust生态库,帮助我们解决很多的基建问题,所以这里使用Rust是相当合适的。Rust学习成长曲线:
4、飞鸽IM客户端历史架构的问题如背景中所描述,历史架构存在这两个问题:1)IMSDK与业务JS代码共用Weview资源,接待密集的时候,sdk与业务,互相抢占cpu与io资源,导致容易卡顿、消息延迟;2)多开的账号必须依赖IMWebview存活(否则无法收到消息),内存线性增长。
5、飞鸽IM客户端新架构与预期目标具体是:1)Rust独立进程承担所有的imsdk的计算压力,可以大幅减轻js线程压力,可提升压力场景接待体验;2)RustimSDK解除浏览器中的IO限制(如同域名并发数限制);3)解除Webview存活依赖,依靠rust进程也可收消息,为更多账号的多开能力提供了铺垫。
6、先用Rust进行技术可行性验证为了验证推测切实可行,我们提前做了完备的POC验证。在POC中,我们针对“单进程单线程模型”、“多进程模型”、“多线程模型”,这三种模型搭建了mvpdemo,即简易的客服聊天模型,并进行压力测试,并监测其内存、cpu等指标。通过POC,我们得出的结论是:具体就是:1)rust整体优于js,计算占比越重,优势越明显(高压时cpu差别能到达3倍以上);2)架构选型上,rust进程独立是最好的方案,稳定性更优、性能损耗相差较小。
8、新架构实施阶段1:RustSDK工程基建造房子先得有一个地基——Rust工程的基础建设,是Native业务的前置条件!桌面端同学牵头搭建了整个RustSDK地基,地基解决的问题如下图所示:需要做的工作:1)业务容器:有规律的组织代码结构,进行业务隔离、资源隔离;2)跨进程调用封装:降低业务调用难度;3)建设日志系统、日志回捞:降低排查问题的难度;4)构建跨平台异步执行环境:简化异步代码编写,底层封装,便于跨平台代码迁移;5)跨平台编译,跨平台集成;6)......
13、新架构带来的收益压力评测:数据表现:解读一下:1)客服发送消息,大盘端到端耗时降低40%;2)消息发送成功率三个9->四个9;3)im页面大盘卡顿率降低15%;4)密集接待场景,卡顿率降低50%。全量至今,再无大量进线导致卡顿的反馈。回访历史反馈用户,皆无因大量接待导致的卡顿现象