Jack Jiang

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

本文来自QCon全球软件开发大会王劲鹏的技术分享,下文进行了排版优化和修订。

1、引言

性能和体验在 iOS / Android 双端场景下已经是一个较为成熟的话题,但随着鸿蒙 OS 的发展,端侧开发者需要更多的关注多端场景的差异性。

本次分享的主题是小红书在鸿蒙平台上的工程实践,主要聚焦于性能优化和探索。* PPT讲稿原文下载:小红书鸿蒙OS下的性能优化探索与实践(PPT)[附件下载]》)

先介绍一下自己的背景。之前一直从事大前端领域的工作,主要专注于跨端和容器化方案。也曾手写过一个跨端框架,名为 Doric,它可以对标 React Native、Vue Native 和 Flutter 等。Doric 框架在落地时表现良好,还支持了一些自研的 3D 引擎方案。除此之外,我还有播放器内核研发经验,以及大前端常规体系建设和 CI/CD 流水线的工程经验。未来,我将持续关注大前端的演进,尤其是鸿蒙这样的多端和跨端平台。

从 2023 年开始,鸿蒙的优势愈发明显,已经成为可与 iOS、安卓媲美的第三大移动操作系统。从一些抖音视频中也可以看出,鸿蒙在流畅性方面甚至在某些层面上超过了 iOS。

今天的分享内容分为四个部分:

  • 1)介绍整个历程和背景;
  • 2)介绍鸿蒙 OS 的相关能力和小红书在该平台上的优化实践;
  • 3)通过鸿蒙 OS 提供的性能验证工具,展示小红书在鸿蒙平台上的性能优化验证方法、优化后的性能提升以及具体的收益和结果;
  • 4)总结和展望。
 
 

2、内容分享和整理

分享者:王劲鹏,内容审校和编辑:Kitty。

 王劲鹏:小红书鸿蒙工程师。目前主要负责小红书鸿蒙版的研发和工程建设,曾从事过大前端架构设计、研发效能等方向的工作,在终端架构演进、性能优化以及跨端容器和动态化等方面具备长期实践及深厚经验,持续关注大前端技术体系,鸿蒙以及多端的演进。

3、版本历程和开发背景

3.1 小红书迭代历程

从 2023 年年中开始,鸿蒙的“千帆计划”正式启动,并很快升级为“鸿飞计划”。小红书作为 7 家头部合作商之一,率先支持了鸿蒙,并于 2023 年 11 月中旬上线了一个基础版的 beta 版本 APP。这个版本主要包含笔记浏览和视频笔记浏览两大功能,以及一些简单的个人设置。当时,小红书的动作非常迅速,可以说是头部应用厂商中对华为支持最为积极的品牌之一。

在整个鸿飞计划中,我们规划了三个核心里程碑:除了 2023 年 11 月的 beta 版本外,还包括 2024 年 6 月的 HDC 版本和 2024 年 9 月的商用版本。HDC 版本主要是针对华为正式宣发鸿蒙 3(HarmonyOS Next)开发者测试的情况。在 HDC 版本中,我们上线了许多小红书特有的存量功能,包括视频拍摄、图文拍摄以及多设备协同等创新特性。而到了 2024 年 9 月的商用版本交付时,小红书的核心功能已经基本与主端对齐。考虑到鸿蒙的开发周期仅有一年,小红书的鸿蒙 APP 在这一年中要对齐开发了十年甚至十几年的安卓和 iOS 版本,难度和压力都非常巨大。

到 2024 年 9 月,除了对齐双端的所有功能外,我们还开发了许多其他功能,包括华为支持的创新特性,例如智能拖拽——用户可以将图片拖拽到中转站或小艺等场景。此外,商用版本还支持了用户呼声较高的 HDR 或 Moonlight Photo 拍摄能力。

3.2 纯血鸿蒙与安卓的区别

我从几个维度来对比一下纯血鸿蒙和安卓 OS 的主要区别。

内核架构纯血鸿蒙的本质是微内核,而安卓是基于 Linux 宏内核。微内核只提供基础的内存和文件管理能力,驱动和其他系统能力都在 OS 之外。这样做的好处是系统稳定性极高,即使应用崩溃,也不会导致整个系统崩溃(system crash)。而在 Linux 宏内核中,应用的不当行为可能会直接导致系统崩溃。

多设备适配鸿蒙目前支持多种设备类型:包括 Mate 60 Pro 这样的直板手机、Mate X5 或非凡大师 XT 这样的双折叠和三折叠手机、平板电脑、车机,甚至华为正在研发的鸿蒙 PC。鸿蒙真正实现了类似 iOS 的多端整合能力,通过一套代码实现多端部署。其工程体系和架构支持单 HAP(Harmony Ability Package)多 HSP(Harmony Service Package)模块,指令集适配了 ARM64 等多种架构,开发者只需根据设备尺寸适配 UI 展示即可。例如,在 2024 年 9 月 的华为全场景设备发布会上,余承东展示了小红书在从直板机到双折叠、三折叠设备上的适配能力,完全实现了响应式编程,不同设备形态下有不同的浏览体验。

开发工具和编程模型鸿蒙的开发工具和编程模型与安卓差异较大。鸿蒙更类似于 Flutter 的嵌套型容器布局,而不是安卓那种面向对象的开发方式。在语言层面,鸿蒙完全封装了底层逻辑,采用类似前端 Flux 单向数据流模式,通过数据变更驱动 UI 刷新。这种模式类似于前端 Redux 或 MobX 框架中的 state 管理 。

从 2024 年 10 月 8 日公测开始,鸿蒙的应用生态正在逐渐繁荣。不过,目前像微信这样的应用还处于抢先体验阶段。相比之下,安卓的生态已经相对成熟。鸿蒙的最终目标是打造全场景智能设备生态,涵盖所有终端设备,以及基于 OpenHarmony 内核开发的物联网终端。它还支持多种芯片体系,例如瑞芯微 RK3568 等。

3.3 小红书鸿蒙应用架构层级

小红书经过一年的迭代,其整体应用架构已经基本成熟。目前,整体代码量接近 200 万行,达到了一个较高的复杂度。在一般成熟的 APP 架构中,通常会包含一些基础底层能力,例如网络、磁盘存储、埋点体系、APM(应用性能管理)系统,以及一些通用组件和能力。对于鸿蒙平台,小红书还具备一些特殊的公共通用能力。

我们开发了一个“一多框架”,这是一个支持一套代码多端部署的具体框架体系。通过这个框架,我们实现了多设备的断点控制功能。用户可以根据设备的尺寸和类型进行适配,因为华为设备支持多端投屏。例如,用户可以在手机上浏览小红书,然后将内容投屏到车机上。比如用户购买了一辆问界汽车,可以在车内通过车机继续浏览手机上的小红书内容,这种场景在驾驶时尤其有用。

除了底层框架,对于上层业务,小红书还有一套自研的组件库方案,这套组件库承载了上层业务的多种功能,包括图文笔记、视频笔记浏览,以及一些 Hybrid 容器能力。小红书本质上在跨端开发中仍然使用了 React Native(RN)和类 Web 技术。RN 引擎由华为内部合作提供,采用了自研的 ohos 方案,用于解决 React Native 的 bundle 和 JS 加载以及渲染问题。此外,还包括产品定制层,这里涵盖了所有相关的设备适配内容。

 3.4 性能优化与实践

目前,安卓和 iOS 在性能优化方面已经相当成熟,包括如何分析性能热点问题、有哪些工具以及最佳实践等。然而,对于鸿蒙来说,它是一个全新的系统。直到 2024 年年中,鸿蒙的稳定性和流畅性都还存在一些问题。这里重点讲述小红书在 2024 年与华为一起进行了哪些实践,以提升应用的性能和用户体验。

我们定义了一个性能指标场景。这个指标体系是小红书与华为共同探讨的结果,因为华为有一个性能工厂,它对每个应用的评级都有一个 S 标标准。小红书与华为一起确定了针对小红书场景需要观测的具体指标。性能优化的核心是慢函数指标,它主要包含两部分:过程时长和应用体验的流畅性。

过程时长主要包含以下三点:

  • 1)冷启动时长:这是用户最关心的指标之一,即从点击应用图标到应用完成动画并展示第一帧的时间。对于多数应用,首页通常有缓存机制。例如,小红书会缓存用户上次刷新的笔记,淘宝会缓存用户上次浏览的商品内容;
  • 2)场景完成时长:指完成某个特定场景所需的时间;
  • 3)应用响应时长:指用户操作界面后,界面真正发生变化的时间,即响应时延。

流畅性方面,最基础的观测指标是平均 FPS(帧率),包括丢帧数、最大连续丢帧数、丢帧卡顿次数以及卡顿率。卡顿率可以通过量化计算得出:当一个场景中出现丢帧时,丢帧的时长与场景总时长的比值即为卡顿率,它是一个小于 1 的百分比数值。

3.5 OS 能力 & 优化实践

首先,针对 IO 场景,我们进行了相应的优化。

鸿蒙 OS 的系统能力主要分为以下三个方面:

  • 1)并行化能力鸿蒙 OS 提供了两种并行化能力:Worker 和 TaskPool。Worker 类似于传统的线程模型,每个 Worker 都有自己的内存空间和执行单元,支持通过消息(message)进行通信。TaskPool 则类似于协程或线程池,能够动态管理线程数量,支持标记为 @concurrent 的函数直接在任务池中调度和运行。这两种机制都支持线程间隔离,内存不共享;
  • 2)多线程通信和数据传输在多线程通信方面,鸿蒙 OS 支持序列化数据传输和基于消息(message)的通信机制。此外,还引入了事件发射器(Emitter)用于系统事件的发布和订阅。这种机制允许线程间通过消息传递来实现复杂的交互逻辑;
  • 3)同步转异步机制鸿蒙 OS 支持基于 Promise 的异步编程模型,包括 async 和 await 语法,以及 then 和 catch 方法。这种机制能够有效提升应用的响应性和用户体验。

4、并行化能力

在并行化能力方面,鸿蒙 OS 提供了两套基础实现方式。开发者可以通过 RTS(运行时系统)实现并行化,也可以通过底层库(如 C++ 标准库中的)实现。不过,如果完全依赖底层库,可能会导致开发效率下降。为了满足业务需求,鸿蒙 OS 在年初引入了 Worker 和 TaskPool 能力。Worker 类似于传统的线程模型,每个 Worker 都有独立的内存空间和执行单元,支持通过消息进行通信。消息可以包含可序列化的数据,也可以通过指针直接迁移数据。TaskPool 则类似于线程池,能够动态管理线程数量,支持标记为 @concurrent 的函数直接在任务池中调度和运行。与安卓平台的线程池不同,鸿蒙 OS 的 TaskPool 会根据硬件条件和任务负载动态调整线程数量。这种机制避免了安卓平台中因线程池数量过多而导致的系统资源消耗问题。

接下来我们对比鸿蒙 OS 的 Worker 并行化能力和安卓端的相关特性。从多个维度来看,Worker 本质上不推荐手动创建,而是通过系统配置 build-provider.json 绑定 ETS 文件来实现创建。这一点与安卓端并无明显差异,安卓端可以通过 THREAD 等方式启动线程。

在鸿蒙 OS 5.0 以下版本(如 4.2 版本)中,主要运行的仍然是安卓系统。这种情况下,安卓线程数量存在上限,这对应用开发者来说是一个挑战。如果 SDK 集成过多,线程数可能超标,进而导致应用被系统强制终止,或出现业务场景异常崩溃等稳定性问题。

数据传输方面:鸿蒙 OS 为了优化 Worker 的性能和负载,对 Worker 的数量和单个 Worker 的传输上限进行了限制。鸿蒙 Worker 的单个传输上限类似于安卓中的 Binder 机制,也存在类似的传输限制。不过,安卓线程通常没有严格限制,因为线程本质上是一个内存拷贝过程,除非开发者通过指针等方式自定义线程间数据传输。

在传输格式上:鸿蒙 OS 支持通过 Sendable 接口进行数据传输。Sendable 是一种注解方式定义的数据结构,具有传染性,即如果一个类被标记为 Sendable,其关联属性也必须是 Sendable 类型。鸿蒙 OS 支持基础数据类型(如 number、string)和集合类型作为 Sendable 传输的内容。对于跨模块调用,鸿蒙 OS 不允许 Worker 跨 HAP 或跨 HSP 调用。相比之下,安卓应用通常运行在一个或多个 Dex 文件中,允许跨 Dex 或跨模块的线程间调用。

TaskPool 类似于双端的协程概念,是一种轻量级线程,仅存储函数。不过,TaskPool 与协程有所不同,它独立于任务维度,且任务执行时长有限制(超过 3 分钟会被系统自动回收)。安卓平台可以通过 ASM 插桩技术对线程的创建和执行进行监控和优化,但轻量级线程或协程的实现通常依赖于线程池或协程机制。

TaskPool 中的任务默认支持数据转移(transfer),不支持拷贝。此外,TaskGroup 不支持 SDK 初始化包的加载。某些同学习惯在异步线程中触发 SDK 的行为,在鸿蒙 OS 上可能会因 TaskPool 生命周期结束而导致变量被释放。

关于并行化数据传输的 Sendable 概念:Sendable 通过系统提供的 SharedHeap(共享堆)实现传输。共享堆与本地堆(local Heap)的区别在于,共享堆支持 Sendable 化数据的传输,而本地堆则需要序列化。共享堆的管理和控制耗费了华为专家大量时间和精力,其中还涉及复杂的异步锁(async lock)机制。在 RTS 并发实例期间(包括 Worker、TaskPool 等),数据可以通过 Sendable 传递,但 Worker 需要使用单独的 API。TaskPool 则完全支持 Sendable 的直接传输。这种异步锁机制允许在 TaskPool 或 Worker 中锁定其他任务中的某些函数,实现线程间的同步,类似于安卓中的 synchronized 或其他锁机制。

5、小红书典型并行化场景

小红书在一些典型化场景中已经实现了并行化处理。例如,网络请求是一个典型的耗时操作,因为请求过程中涉及验签和安全能力的处理,这些操作如果在主线程中同步完成,可能会导致应用掉帧。当用户滑动时,掉帧现象会非常明显,这通常是由于大量计算引起的。为了解决这一问题,我们采用了 Worker 化的方式,将这些操作移到 Worker 线程中,从而避免主线程的卡顿。

在进行埋点时,可能会涉及数据库的 IO 操作,这些操作也不建议在主线程中执行。通过将这些操作放到 Worker 线程中,可以有效避免对主线程的影响。

针对双列布局中的图片和资源预加载,我们采用华为自研的 RCP 网络解决方案(类似于 HTTP),通过 Worker 线程在远端进行下载,并在完成后将结果返回到主线程。此外,TaskPool 的应用场景也非常广泛,例如文件上传、多媒体操作以及启动任务的编排等。TaskPool 的优势在于轻量化,避免了线程上下文切换带来的不必要耗时。

关于冷启动和首刷场景的优化。这部分主要包括两个方面:模块的懒加载和动态组件的复用池。懒加载是应用开发中常见的优化手段,类似于安卓端的 class order 机制。当应用不需要某个类时,可以延迟加载该类,直到真正需要使用时才加载。这种方式可以显著提高冷启动阶段的代码加载效率,从而大幅降低冷启动时长。

动态组件和组件复用池则是为了解决 UI 组件重复创建的问题。在应用中,可能会有多种相同类型的 UI 组件(例如小红书中的笔记组件)。为了避免重复创建带来的开销,我们希望在运行时尽量复用已有的组件,而不是频繁地创建和销毁。

6、类前端视角下的模块懒加载

我们通过特定的分析工具对懒加载进行了深入分析。如图所示,我们能够识别出启动过程中加载的各种模块,包括 RNOH(React Native on Harmony)、Web engine(网页引擎)、Red Player(播放器)等组件。这些模块的加载过程涉及到多个.so 文件,即共享对象文件。

 通过自上而下的分析方法,我们可以清晰地看到每个模块加载的具体耗时。进一步分析这些.so 文件与 RTS(运行时系统)的关联,以及它们所引入的 Napi 的 TS 文件。我们进行了懒加载潜在对象的分析,发现许多 RTS 实际上并不需要的类文件已经被加载。这是因为开发者在编写代码时,可能并未充分考虑到导入一个类或方法对应用启动延迟的影响。

为了优化这一过程,我们的目标是减少字节码中需要加载的类文件数量,从而加快应用的冷启动速度。华为提供的编译器能够将 RTS 编译成 Ark bytecode(方舟字节码),这是一种高效的字节码格式。通过减少需要加载的类文件数量,我们可以显著提高应用的启动速度。

华为还提供了一种懒加载的导入方式,只有在真正需要使用某个类时,它才会被加载。这种懒加载机制有助于减少应用启动时的资源消耗。这引发了一个问题:为什么华为不默认采用全懒加载方式,即只有在使用时才加载类文件呢?我已经将这个问题反馈给华为,并且系统侧可能会考虑在未来的版本中默认采用懒加载方式,同时仍然允许用户手动选择非懒加载的方式进行类文件的加载。

7、动态组件

在小红书的首页场景中,笔记卡组件在多个场景中被复用。为了避免重复创建 UI 导致的性能消耗,我们采用了动态组件的概念。动态组件的核心原理是利用占位符来延迟组件的创建,这与 Android 开发中使用 Stub 模式的概念相似。在这种模式下,可以使用一个代理对象(stub)来代表尚未初始化的组件,从而延迟组件的创建过程。当真正需要渲染组件时,再将渲染内容填充进去,从而避免每次调用构建函数(如 build)时的耗时。

占位逻辑通过系统的 API 实现,涉及到 NodeContainer 和 NodeController 的绑定关系。Container 和 Controller 一一映射,由 NodeCore 进行管理。Container 仅管理当前展现的内存部分,使用完毕后需要将其放回池中进行回收和再利用。以冷启动首刷为例,在启动阶段可以先获取磁盘上的笔记内容,然后在 BuilderNode 中预先创建多个 Image 组件。这样,在等待网络或推荐接口响应时,Image 组件已经创建完毕,从而在首页刷新时可以立即使用这些组件,这对于提高首刷非常有益。

 对于组件复用池,当动态组件不再使用时,需要将其返回到组件池中。对于自定义组件,通过 NoteContainer 占位方式,由 NodeController 进行管理。在需要创建子组件时,先在 NodePool 中查找,如果找不到,则创建新组件;如果找到,则尝试复用。流程图展示了从 Container 装载 NodeItem 开始,通过 NodePool 查找,如果找到则进行条件判断和复用。

组件的新建和复用过程中,如果找到对应的 NodeItem,则调用 build 方法并更新自定义组件的状态,完成复用。如果有对应的 NodeItem,可以直接通过 update 函数更新内部状态并刷新 UI。但要注意,update 方法可能会因状态变量过于复杂而导致更新延迟,出现图像残影。因此,需要拆分 state,使其足够小,以确保状态变更到通知 UI 的时间缩短,消除残影。

我们的策略是优先在 NodePool(节点池)中查找可用的 NodeItem(节点项)。如果 NodePool 中存在可用的 NodeItem,我们就直接使用它,并通过 getNode 方法进行 item 绑定,随后更新其状态以实现复用。如果 NodePool 中没有找到对应的 NodeItem,那么我们将通过 makeNode 方法调用 build 函数来创建新的节点项。

完成组件的复用后,我们需要将这些组件返回到缓存池中,以便在未来可以再次使用。这个过程涉及到 NodeContainer(节点容器)和 NodeController(节点控制器)的销毁,并将 NodeItem 重新放回 NodePool 中。为了更有效地管理缓存,业务层可以利用 LRU(最近最少使用)算法,或者鸿蒙系统提供的 LRUCache 和 LiUHashMap 等数据结构,来自定义缓存的大小,从而优化组件的复用和缓存策略。

8、滑动类场景

在小红书应用中,滑动类场景非常普遍,包括推荐页的子频道、个人页中的收藏点赞以及用户自己发布的笔记,还有搜索结果页中的搜索结果和用户商品等,这些都是双列滑动场景。这些双列滑动场景占据了小红书用户体验的 90% 到 95%,因此,滑动体验的流畅性对于用户的整体体验至关重要。

为了提升滑动场景的流畅性,小红书采用了 RCP 框架来优化网络资源的获取。RCP 是华为提供的一个系统组件能力,主要解决网络资源获取效率问题。通过 RCP,开发者可以在需要时发起网络请求,并自定义资源的写入地址,如文件或 ArrayBuffer。RCP 负责高效地将资源写入指定位置,而在不需要时,可以取消 RCP 请求,从而优化资源管理。

 RCP 的核心能力在于能够取消请求,并对弱网场景进行了优化,其建联过程优于 HTTP 1.1 或 2.0。基于 RCP,小红书还应用了华为俄研所提供的 Prefetch 方案。Prefetch 方案在瀑布流组件的可见区变更时,通过 worker 线程(如 prefetched worker)启动资源获取,当不可见时关闭,从而优化快速滑动场景,减少不必要的带宽消耗。

在快速滑动过程中,有些 item 可能短暂消失,对于双端场景,网络请求可能已经发出且在途,无法取消,导致带宽浪费。Prefetch 和 RCP 结合的方式可以优化这种快滑场景,防止真正想要看的内容出现白块。Prefetched worker 线程管理多个 RCP 请求,每个请求都有完整的生命周期。当通过 RCP 请求获取到所需资源时,会通知主线程,主线程根据地址加载资源到 Image 组件或占位符 RQI 组件中。

在小红书的开发过程中,我们遇到了一些性能热点问题,这些问题大多是通过 Code Linter(代码检查工具)检测出来的。由于开发节奏快,开发者在编写代码时可能难以关注到性能问题,因此需要 CI(持续集成)检查工具来辅助检查。

常见的性能热点包括:

1)在列表场景中频繁使用的 LadyForEach 组件,需要指定 key 以实现列表复用。如果开发者忘记指定 key,Code Linter 会报错提示;

2)在 onClick 或 onVisible 等函数中编写空 callback(回调函数)。当这些空 callback 积累到一定数量(如几百个或上千个)时,可能会严重拖慢应用性能。Code Linter 可以扫描出这类问题;

3)未使用 TaskPool 处理网络资源。例如,Image Bitmap 直接传递 URL 进行同步加载,当网络阻塞时会导致 UI 线程卡顿;

4)复杂的 ETS 组件在列表场景下未实现重用。未设置重用的 ETS 组件在列表滚动时需要重新构建,非常耗时。组件嵌套层级过深也会导致性能问题。在安卓端,布局检查器建议容器嵌套不超过四层;

5)使用 JSON.stringify 进行对象序列化。JSON.stringify 有一定耗时,尤其在处理 100KB 左右的数据时,可能需要 10 毫秒左右。Code Linter 会提示这部分性能问题,但是否需要转异步线程需要开发者自行判断;

6)调用 Image 的 syncLoad(同步加载)。在某些场景下,如转场动画,需要同步加载 image 以保证连贯性。但如果 image 是非磁盘资源(如网络资源),会导致卡帧。Code Linter 可以扫描出这类问题;

7)关于编译器的优化。ETS 组件应避免嵌套过深。如果嵌套过深,可以将每层函数通过系统的 builder param 或 builder 函数转换。使用 @builder 注解标识的函数会在编译期间与 ETS 代码整合,从而提高编译器优化效果。

Code Linter 支持全量扫描和基于 Git DIFF 的增量扫描,但目前华为的 Code Linter 还不能与 Git Prehook 关联,导致无法在流水线上自动检查。虽然 CI 检查阶段已有 Code Linter,但本地代码提交阶段仍需手动运行脚本,无法实现自动检查。我们正在催促华为解决这一问题。

 

9、UI 重载场景分帧方案

在处理 UI 重载场景时,我们采用了一种称为分帧方案的方法。分帧这个术语的含义是,当应用在一帧内无法完成所有绘制工作,或者在多帧内都无法完成时,会导致屏幕卡顿现象。尽管用户可以看到画面,但却无法进行滑动或操作。在这种情况下,分帧方案就显得尤为合适。虽然分帧方案可能看起来不是最优雅的解决办法,但它确实能够有效地解决性能问题,使应用性能达到预期标准。分帧方案虽然看似是一种应急措施,但它能够帮助应用性能达标。

分帧方案的流程大致如下:假设我们有数据 a、b、c 需要渲染,未采用分帧方案前,数据 a、b、c 会同时到达并触发状态变更,进而驱动整个 UI 进行刷新。这会导致在一帧内需要绘制大量 UI 组件,从而影响应用性能。为了解决这个问题,我们采用分帧方案,将数据 a、b、c 拆分开,分别在不同的帧中进行渲染。例如,数据 a 在第一帧中渲染完成后,通过调用宏观指令让其进入下一阶段,然后在下一帧中更新数据 b,依此类推。

 

在小红书的图文笔记场景中,分帧方案得到了应用。当用户在首页的双列场景中点击一篇笔记进入笔记详情页时,这个过程涉及到许多组件的加载。我们可以将这些组件拆分成不同的帧,例如帧 a、帧 b 和帧 c。对于用户而言,他们通常希望在第一时间看到整个大屏的画面,因此我们会优先在帧 a 中展示大图。而在帧 b 和帧 c 中,我们再处理顶部导航栏或底部交互区等内容。通过这种分帧策略,我们能够确保用户在第一时间看到最关键的内容,同时避免了因为一次性加载过多组件而导致的性能问题。

10、鸿蒙NEXT调优工具

传统的主观工具对于鸿蒙 OS 的性能分析仍然适用。例如,抖音和小红书都通过竞品分析来进行主观测评。这种能力主要是通过录屏来展示整个流程的耗时和时长,特别适合评估冷启动完成时延和转场过程的性能。通过录屏,我们可以逐帧查看用户从点击开始到结束的帧数和真实时长,以此来衡量整个过程的持续时间。

10.1 鸿蒙性能分析工具:IDE Profiler

除了主观工具,我们还可以使用 IDE 提供的性能分析工具,如 Profiler,来分析慢函数。由于 ArkTS 编程语言框架主要通过 RTS 和 NAPI(原生应用接口)进行关联,因此需要能够查看 ArkTS 和 NAPI 的整个堆栈层级。这与安卓有所不同,因为当 Java 通过 Java Native API 与原生代码交互时,堆栈并不那么容易查看。

在小红书的性能分析中,我们展示了一个整体线程分析的例子。在左侧,可以看到小红书的主线程(如 com 点开头的线程)、Daemon 线程、Worker 线程以及 FFRT 线程。FFRT 是一种运行函数流的线程,可以执行 TaskPool 上的函数。在下图右侧,我们可以看到在 RTS 环境下的分析结果,其中顶部显示了 NAPI 调用,底部则是一些 C++ 函数。整个调用栈和它们的执行时长是通过一种自上而下的视图来展示的。利用这种视图,我们可以精确地识别出哪些慢函数是造成界面卡顿的原因。

10.2 性能场景测试工具:DevEco Testing

DevEco Testing 是一个性能测试工具,它的功能非常全面,性能测试只是其中的一部分。除了性能测试,它还支持多种测试场景,包括 debug testing。在 debug testing 场景中,用户可以自定义业务场景,监测 CPU 的耗时和负载、GPU 的耗时和负载、设备发热情况以及功耗等问题。

使用 DevEco Testing 进行性能测试的过程如下:首先定义测试场景,然后捕获主帧数据。一旦开始捕获,就可以观测到 FPS(帧率)、GPU 负载以及整体功耗等数据。完成性能数据捕获后,工具会生成一份报告,为用户提供了一个完整的场景分析。不过,目前场景定义还缺乏脚本化能力,需要人工操作辅助。未来,我们期望能够实现场景定义的脚本化配置,类似于自动化测试。这样,就可以通过自动化工具,实现更高效的测试流程。

11、小结与展望

在对性能场景进行优化后,我们可以看到显著的收益。在实验室环境下的测试显示,冷启动时间可以降低 50%,响应时延可以低于 100 毫秒,完成时延则保持与双端持平或更优。在流畅性方面,在多场景和重载场景下均实现了 0 丢帧的成果。需要注意的是,这里的测试是在非重载模式下进行的,即没有同时运行多个资源密集型应用,如《王者荣耀》或《和平精英》等。在这种条件下,我们的核心场景,如冷启动、搜索和个人页等,都能够与双端完全对齐。

展望未来,有几个方向:

1)首先:我们希望能够在全场景下实现组件复用,以最大程度地实现 UI 复用。这样可以在多个业务之间的转场或 UI 创建过程中,将不必要的 UI 创建和消耗降到最低。

2)其次:我们正在考虑代码延迟加载的 lazy 机制。华为内部可能将其作为通用的解决方案,但在实施过程中我们发现了许多问题,例如全 lazy 加载可能会影响第三方 SDK,如支付宝等,因为它们可能进行了额外的二进制优化,导致加载失败或无法响应。因此,我们期望通过代码延迟加载来实现持续治理,但目前它可能还不适合全场景的 lazy import。

3)最后:我们关注防劣化问题,即在每个版本发布时,我们不希望性能指标出现劣化。我们希望能够在开发阶段就定义劣化指标和具体数据,以防止应用劣化。这部分可能需要借助 DevEco Testing 和主观测评的方式来实现。包括我们关注的指标,例如冷启动和流畅性等,未来可能会纳入防劣化场景。目前,我们的 CI 环节或 RC 环节,包括流水线的性能管控和代码 CR 机制,都能够规避这类问题。

12、相关资料

[1] 鸿蒙NEXT官方开发指南

[2] 一年撸完百万行代码,企业微信的全新鸿蒙NEXT客户端架构演进之路

[3] 鸿蒙NEXT如何保证应用安全:详解鸿蒙NEXT数字签名和证书机制

[4] 开源IM聊天程序HarmonyChat:基于鸿蒙NEXT的WebSocket协议

[5] 微信纯血鸿蒙版正式发布,295天走完微信14年技术之路!

[6] 即时通讯框架MobileIMSDK的鸿蒙NEXT端详细介绍

[7] 即时通讯框架MobileIMSDK的鸿蒙NEXT端开发者手册

[8] 拥抱国产化:转转APP的鸿蒙NEXT端开发尝鲜之旅

[9] 微信Windows端IM消息数据库的优化实践:查询慢、体积大、文件损坏等

[10] 微信技术分享:揭秘微信后台安全特征数据仓库的架构设计

[11] IM跨平台技术学习(九):全面解密新QQ桌面版的Electron内存优化实践

[12] 企业微信针对百万级组织架构的客户端性能优化实践

[13] 揭秘企业微信是如何支持超大规模IM组织架构的——技术解读四维关系链

[14] 微信团队分享:详解iOS版微信视频号直播中因帧率异常导致的功耗问题

[15] 微信团队分享:微信后端海量数据查询从1000ms降到100ms的技术实践

[16] 大型IM工程重构实践:企业微信Android端的重构之路

[17] IM技术干货:假如你来设计微信的群聊,你该怎么设计?

[18] 微信团队分享:来看看微信十年前的IM消息收发架构,你做到了吗

[19] 总是被低估,从未被超越,揭秘QQ极致丝滑背后的硬核IM技术优化

[20] 首次公开,最新手机QQ客户端架构的技术演进实践

[21] 大型IM稳定性监测实践:手Q客户端性能防劣化系统的建设之路


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

posted @ 2025-05-19 11:24 Jack Jiang 阅读(194) | 评论 (0)编辑 收藏

     摘要: 全平台开源即时通讯IM聊天框架MobileIMSDK的服务端开发指南,支持鸿蒙NEXT  阅读全文

posted @ 2025-05-15 12:27 Jack Jiang 阅读(85) | 评论 (0)编辑 收藏

一、基本介绍

MobileIMSDK是一套全平台原创开源IM通信层框架:

  • 超轻量级、高度提炼,lib包50KB以内;
  • 精心封装,一套API同时支持UDP、TCP、WebSocket三种协议(可能是全网唯一开源的);
  • 客户端支持iOS、Android、标准Java、H5、微信小程序、Uniap、鸿蒙Next(Demo完整源码);
  • 服务端基于Netty,性能卓越、易于扩展 new;
  • 可与姊妹工程 MobileIMSDK-Web 无缝互通实现网页端聊天或推送等;
  • 可应用于跨设备、跨网络的聊天APP、企业OA、消息推送等各种场景。

二、源码仓库同步更新

GitHub.com:

码云gitee:

三、设计目标

让开发者专注于应用逻辑的开发,底层复杂的即时通讯算法交由SDK开发人员,从而解偶即时通讯应用开发的复杂性。

四、框架组成

整套MobileIMSDK框架由以下7部分组成:

  1. Android客户端SDK:用于开发Android版即时通讯客户端,支持Android 4.0及以上版本,查看API文档
  2. iOS客户端SDK:用于开发iOS版即时通讯客户端,支持iOS 12.0及以上版本,查看API文档
  3. Java客户端SDK:用于开发跨平台的PC端即时通讯客户端,支持标准Java 1.6及以上版本,查看API文档
  4. H5客户端SDK:查看精编注释版
  5. 微信小程序端SDK:查看精编注释版
  6. Uniapp端SDK:查看精编注释版
  7. 鸿蒙Next端SDK:SDK暂无开源版(查看精编注释版),Demo完整工程源码
  8. 服务端SDK:用于开发即时通讯服务端,支持Java 1.7及以上版本,查看API文档

整套MobileIMSDK框架的架构组成:

MobileIMSDK一直在持续开发和升级中,鸿蒙Next客户端是MobileIMSDK工程的最新成果。

五、技术特征

  • 久经考验:历经10年,从Andriod 2.3、iOS 5.0 时代持续升级至今(绝不烂尾);
  • 超轻量级:高度提炼,lib包50KB以内;
  • 多种协议:可能是全网唯一开源可同时支持UDP、TCP、WebSocket三种协议的同类框架;
  • 多种网络:精心优化的TCP、UDP、WebSocket协议实现,可应用于卫星网、移动网、嵌入式物联网等场景;
  • 多端覆盖:客户端支持iOS、Android、标准Java、H5微信小程序Uniapp鸿蒙Next
  • 高效费比:独有的UDP协议实现,无连接特性,同等条件下可实现更高的网络负载和吞吐能力;
  • 消息走向:支持即时通讯技术中消息的所有可能走向,共3种(即C2C、C2S、S2C);
  • 粘包半包:优雅解决各端的TCP经典粘包和半包问题,底层封装,应用层完全无感知;
  • QoS机制:完善的消息送达保证机制(自动重传、消息去重、状态反馈等),不漏过每一条消息;
  • 健壮可靠:实践表明,非常适于在高延迟、跨洲际、不同网络制式环境中稳定、可靠地运行;
  • 断网恢复:拥有网络状况自动检测、断网自动治愈的能力;
  • 原创算法:核心算法和实现均为原创,保证了持续改进和提升的空间;
  • 多种模式:预设多种实时灵敏度模式,可根据不同场景控制即时性、流量和客户端电量消耗;
  • 数据压缩:自有协议实现,未来可自主定制数据压缩,灵活控制客户端的流量、服务端网络吞吐;
  • 高度封装:高度封装的API接口,保证了调用的简易性,也使得可应用于更多的应用场景;
  • Web支持:可与姊妹工程 MobileIMSDK-Web 无缝互通实现网页端聊天或推送等;
  • 扩展性好:服务端基于Netty,继承了Netty的优秀高可扩展性;
  • 性能优异:服务端继承了Netty高性能、高吞吐特性,适用于高性能服务端场景。

六、演示程序

  1. Android客户端 Demo:点此安装和使用
  2. iOS客户端 Demo:点此安装和使用
  3. Java客户端 Demo:点此安装和使用
  4. H5客户端 Demo:点此查看介绍
  5. 微信小程序端 Demo:点此查看介绍
  6. Uniapp端 Demo:点此查看介绍
  7. 鸿蒙Next端 Demo:点此查看介绍 new;
  8. 服务端 Demo:点此安装和使用

七、应用案例

RainbowChat是一款基于MobileIMSDK的产品级聊天APP,更多详情:点击下载体验 或 查看运行截图

① 基于MobileIMSDK的产品级聊天APP:

▶ 详细介绍下载体验 或 查看运行截图

② MobileIMSDK在高网络延迟下的案例:

▶ 某款基于MobileIMSDK的商业商品,曾运营于跨洲际的复杂网络环境下,端到端通信延迟在洲际网络繁忙时可高达600ms以上(与服务端的单向延迟约为300ms左右,而通常大家访问国内主流门户的延迟约为20~50ms),某段时期的非敏感运营数据 点此查看

八、打包下载(all in one)

说明:最新发布版打包内容中,已包含完整的demo源码、sdk源码、api文档、编译后的分发包等。

九、典型应用场景

场景1:聊天APP

应用说明:可用于开发类似于微信、QQ等聊天工具。

消息走向:需使用C2C、C2S、S2C全部类型。

特别说明:MobileIMSDK并未定义聊天应用的应用层逻辑和协议,开发者可自行定义并实现之。

场景2:消息推送

应用说明:可用于需要向客户端实时推送信息的各种类型APP。

消息走向:仅需使用S2C 1种消息走向,属MobileIMSDK的最简单应用场景。

场景3:企业OA

应用说明:可用于实现企业OA的指令、公文、申请等各种消息实时推送,极大提升用户体验,并可延伸至移动设备。

消息走向:仅需使用S2C 1种消息走向,属MobileIMSDK的最简单应用场景。

场景4:企业OA的增强型

应用说明:可用于实现企业OA中各种系统级、用户级消息的实时互动,充分利用即时通讯技术提升传统OA的价值。

消息走向:可使用C2C、C2S、S2C全部类型,这与聊天APP在很多方面已无差别,但企业OA有自已的用户关系管理模型和逻辑,较之全功能聊天APP要简单的多。

十、开发指南

  1. Android客户端开发指南:点此查看
  2. iOS客户端开发指南:点此查看
  3. Java客户端开发指南:点此查看
  4. H5客户端开发指南:点此查看
  5. 微信小程序端开发指南:点此查看
  6. Uniapp端开发指南:点此查看
  7. 鸿蒙Next端开发指南:点此查看
  8. Server端开发指南:点此查看

附录1:Demo截图

1、在鸿蒙Next端运行效果:

>> 编译和运行:查看鸿蒙Next端Demo完整源码

2、Android端、iOS端运行效果

>> 安装和使用:进入Android版Demo帮助页进入iOS版Demo帮助页

3、H5端运行效果

4、微信小程序端运行效果

5、Uniapp端运行效果

6、Windows 运行效果

>> 安装和使用:进入Java版Demo帮助页

7、Mac OS X 运行效果

>> 安装和使用:进入Java版Demo帮助页

8、MobileIMSDK-Web版客户端Demo运行效果:

8.1)MobileIMSDK-Web在手机端浏览器运行效果:(如何获取MobileIMSDK-Web版:点此进入

8.2)MobileIMSDK-Web在PC端浏览器运行效果:(如何获取MobileIMSDK-Web版:点此进入

附录2:基于MobileIMSDK的全功能IM【案例】

>> 关于RainbowChat的更多资料请见:RainbowChat前端APP功能截图网页 (* 推荐 - 真机实拍视频:Andriod端iOS端)。

附录3:基于MobileIMSDK-Web的网页端IM系统【案例】

下图为RainbowChat-Web的主界面更多截图点此进入更多演示视频点此进入):

下图为RainbowChat-Web的主界面[聊天窗全屏时] (更多截图点此进入更多演示视频点此进入):

下图为RainbowChat-Web的主界面[独立UI效果] (更多截图点此进入更多演示视频点此进入):

以上内容同步发布于:http://www.52im.net/thread-52-1-1.html )

posted @ 2025-04-29 15:29 Jack Jiang 阅读(142) | 评论 (0)编辑 收藏

本文由转转技术团队赵卫兵分享,原题“鸿蒙新篇章:转转 APP 的 HarmonyOS Next 开发之旅”,下文进行了排版优化和内容修订。

1、引言

2023 年在华为开发者大会(HDC.Together)上,除了面向消费者的 HarmonyOS 4 之外,华为还推出了面向开发者的 HarmonyOS Next 开发者预览。

而在去年的 6 月份华为开发者大会上,对外开启了 HarmonyOS Next Beta 版,并在当年内正式推出面向消费者的商用版本。

HarmonyOS Next,是鸿蒙生态的一个重要拐点。去年的时候,转转和华为已经达成合作,作为鸿蒙先锋的一员,加入到鸿蒙应用的开发之中来。

客户端从 2023 年 11 月份开始,人力开始逐渐的往这个方向投入,于 2024 年 2 月份正式开始进入业务开发,在 6 月 4 号,对外正式发布了基于 HarmonyOS Next 系统的转转 App 首个版本。

从早期的学习到最终第一个版本上线,我们经历了以下几个阶段:

  • 1)前期的熟悉和学习过程;
  • 2)鸿蒙客户端基建开发过程;
  • 3)首个版本需求范围确定和排期;
  • 4)业务开发;
  • 5)测试;
  • 6)bug 修复/性能调优;
  • 7)上线。

本文将要分享的是转转APP在开发全新鸿蒙NEXT端所遇到的一些问题,对比了鸿蒙开发和 Android、iOS 的不同,总结了这次开发过程中的一些经验等等。希望能带给你启发。

 
 

2、关于作者

赵卫兵:目前负责转转集团 iOS 和鸿蒙系统 App 基础架构和相关基础建设。崇尚开源和分享精神,Sharing is everything ~

转转团队分享的其它几篇技术文章有兴趣也可读一读:

  1. 转转平台IM系统架构设计与实践(一):整体架构设计
  2. 转转平台IM系统架构设计与实践(二):详细设计与实现
  3. Web端IM聊天消息该不该用浏览器本地存储?一文即懂
  4. 手把手教你使用网络编程抓包神器Wireshark
  5. 浅谈网页端IM技术及相关测试方法实践(包括WebSocket性能测试)

3、初识鸿蒙NEXT

3.1 分布式技术

HarmonyOS Next 具备强大的分布式技术,能够实现跨设备协同工作。用户可以无缝地在不同的设备间切换和使用应用,无需感知设备的差异。HDC 大会中如 WPS Office、高德等 APP,使用了应用接续特性,在不同设备中进行流转,令人印象深刻。这点在 iOS 和 Android 中并不完全具备。

3.2 高性能低时延

HarmonyOS Next采用轻量级的微内核设计。

iOS 使用的内核基于 XNU(X is Not Unix)内核,XNU 是一个混合内核,结合了微内核(Mach 内核)的内存管理、任务调度、进程间通信等特性和宏内核(BSD 内核)的文件系统、网络堆栈、用户进程管理等特性。

Android 内核基于修改过的 Linux 宏内核,增加了 Binder IPC、电源管理、安全性等模块和机制,以更好的支持移动设备。

鸿蒙的微内核设计,官方称相比宏内核,具备更高的性能和更低的时延,从而在多任务处理、设备响应和处理能力上具有明显优势。

3.3 自适应UI框架

通过 ArkUI和ArkTS,HarmonyOS Next能够适应各种尺寸和形状的屏幕设备,提供一致友好的用户体验。这个特性在跨设备协同时尤其重要。

3.4 多终端、多OS支持

HarmonyOS Next 不仅仅是一个手机操作系统,还能运行在平板、智能穿戴设备、智能家居设备等多种终端上,统一生态系统。对比苹果的iOS,MacOS,TVOS,WatchOS,确实有些不同。但对于应用开发者而言,其实就是API的能力集合问题,这一点,鸿蒙使用 SysCap 系统能力集合达到了殊途同归的效果。

3.5 更优秀的安全性

在应用安全层面,目前在应用的生态中有以下一些问题:

  • 1)诱导用户下载安装恶意应用;
  • 2)窃取用户数据;
  • 3)强制推送广告;
  • 4)利用漏洞攻击其他应用程序;
  • 5)盗版软件。

这方面,由于Android 的开放性以及侧载安装的支持,问题表现的尤为明显,而 iOS 是一个可以学习的老师。

针对上面的问题,HarmonyOS Next 又是如何应对的呢?

  • 1)做好应用质量的监管,控制应用分发渠道,避免恶意应用分发到用户设备上;
  • 2)提供安全的数据授权机制,避免用户过度授权造成安全威胁;
  • 3)给应用程序开放的系统功能做到不被恶意利用;
  • 4)帮助应用程序最小程度的受到漏洞影响;
  • 5)为应用程序提供有效的核心数字产权保护手段,避免出现盗版软件问题。

具体可以看下图:

(图片来自《鸿蒙生态应用安全技术白皮书 V1.0》)

4、和Android、iOS的开发有何不同?

鸿蒙开发上,和 Android、iOS 还是有不少相似和不同的地方,我挑选感受比较深刻的几个点说下。

4.1 开发语言和工具链

鸿蒙开发使用的是ArkTS 语言,ArkTS基于 TypeScript 做了一些扩展,继承了 TypeScript 的所有特性,是 TypeScript 的超集。

下面是官方的一些介绍:

ArkTS的一大特性是它专注于低运行时开销。ArkTS对TypeScript的动态类型特性施加了更严格的限制,以减少运行时开销,提高执行效率。通过取消动态类型特性,ArkTS代码能更有效地被运行前编译和优化,从而实现更快的应用启动和更低的功耗。

与JavaScript的互通性是ArkTS语言设计中的关键考虑因素。鉴于许多移动应用开发者希望重用其TypeScript和JavaScript代码和库,ArkTS提供了与JavaScript的无缝互通,使开发者可以很容易地将JavaScript代码集成到他们的应用中。这意味着开发者可以利用现有的代码和库进行ArkTS开发。

在开发工具上:使用的 IDE 是 DevEco Studio,基于 IntelliJ IDEA Community 开源版本打造,为开发者提供工程模板创建、开发、编译、调试、发布等功能。华为在这个 IDE 上针对鸿蒙开发易用性上做了大量的工作,包含但不限于编译器,代码实时预览、ArkUI Inspector、Profile 性能分析工具等等。

在包管理上:有点类似前端的 npm 包管理机制,不过在这块,是叫 ohpm,整体上非常相似,但是细节上有一些不同,譬如 package.json 的文件命名、lock 文件的内容信息、独立的开源中心仓等等。仓库这块也提供了私仓部署的方式,采用套件工具中的 ohpm-repo就可以部署到企业内部服务器上。

在调试上:和 Android 的 ADB 类似,鸿蒙这块提供了一个 hdc 的工具,提供了类似查询设备列表、网络、文件、应用安装卸载、shell、日志获取等常用功能。

4.2 开发体验

鸿蒙开发是用 ArkUI,类似 Flutter,SwiftUI 这样的声明式 UI,ArkUI 组件的命名和状态管理和 SwiftUI 比较类似,上手比较容易。

4.3 开发资料和交流

Android 从 2008 年谷歌布,iOS 从 2007 年苹果发布,距离到现在已经有了 16~17 年之久,在这期间,互联网上积累了无数的开发资料和经验分享,也有着大量的开源项目和社区。

而有关 HarmonyOS Next 方面的资料,目前更多的是官方开发指南和开源范例(集中在 gitee 上)。

社区方面,主要是华为开发者论坛,受限于开发者版本的迅速迭代,一些帖子讨论的内容已经过时且不再适用。

而在博客、github 开源上,目前看到的其实并不多,更多的分享还是比较基础,深度有价值的还不多。

目前在这个阶段,更多的是企业和华为合作的情况下,内部使用 Issue 工单系统进行沟通交流。交流主要围绕着需求、Bug 反馈、指南疑问来展开。

譬如:

  • 1)指南资料中提供的能力,不满足诉求,交流是否有更好的解决方案;
  • 2)API 、IDE、工具链表现不符合预期,反馈 bug;
  • 3)系统能力类比 Android、iOS 缺失的特性,交流是否有替代的解决方案。

截止到本篇文章写的时候,转转华为工单交流的总数已达到 270+个。反馈的 bug 和缺失的能力,在后面的开发者预览版本中都被修复或支持了。

印象比较深刻的一件事是:开发和测试期间我们发现了停留在登录页面不动,过个10 分钟左右,系统就会卡死重启,我们一度以为是 App 哪里有 bug。我们通过 hdc hilog 抓取系统输出的日志,发现大约过了 10 分钟左右,log 就会死循环打印,很明显系统底层发生了一些异常。已经晚上快 1 点了,我们兴奋的找到和我们对接这个问题的华为工程师张老师,将视频和日志发送给他,张老师按照复现的路径,也成功复现出来,并且抓取到日志。后面的几天,经过华为伙伴的努力,终于定位到问题所在,是文件句柄 FD 存在泄露的情况,并在下一个开发者版本中推送修复了。

为华为工程师的敬业和效率竖一个大拇指,华为之所以强大,从这件事的跟进和解决效率上,就能理解到为什么。

5、踩坑后总结的几个经验

5.1 类比学习

投入鸿蒙开发的客户端同学,有来自 Android 开发的,也有来自 iOS 开发的,或多或少对另外一端的系统了解的不是很全面。

在学习的过程中,我们发现鸿蒙的一些特性和 API 设计,有些和 iOS 比较像,而有些和 Android 有些像。我们内部经常讨论交流和理解 HarmonyOS Next 的应用层设计问题。在方案选择上,HarmonyOS Next 中都有借鉴和取舍。

这个阶段:我们需要重点理解鸿蒙特有的一些设计概念和思想。譬如 Stage 模型,Stage模型是从 API 9 开始新增的模型,是目前主推且会长期演进的鸿蒙应用模型。在该模型中,由于提供了 AbilityStage、WindowStage 等类作为应用组件和 Window 窗口的“舞台”,这种方式在 Android、iOS 上是不是有类似的概念呢?

如果我们如下类比 Android、iOS。

AbilityStage 和 WindowStage:

  • 1)在 iOS 中,与 UIViewController 和 UIWindow 类似。UIViewController 管理视图层次和界面行为,而 UIWindow 是应用程序的窗口,可以显示内容;
  • 2)在 Android 中,可以类比于 Activity 和 Window。Activity 是应用的单个屏幕,负责界面的创建和管理,而 Window 是 Activity 的顶层视图容器。

UIAbility 和 ExtensionAbility:

  • 1)UIAbility 可以和 iOS 的 UIViewController 以及 Android 的 Activity 相对应,因为它们都是用于管理和显示用户界面的基本单元。
  • 2)ExtensionAbility 可以类比于 iOS 的 App Extension 和 Android 的 Service。App Extension 提供了将功能扩展到系统范围内的能力,而 Service 在 Android 中则是运行在后台的组件,执行长时间运行的操作。

虽然细节有所不同,但大方向上这样对比和类比,会帮助我们快速理解鸿蒙相关开发概念。

5.2 项目管理和风险方案应对

首个版本的开发,几乎涉及到了公司所有的业务部门,我们通过启动会拉齐背景信息,前期让大家梳理到新增一个鸿蒙终端对业务的影响范围,以及解决方案。

1)PlanB 方案:

一些三方 SDK 如微信、支付宝等在前期都是没有的,我们首个版本需要做好 PlanB 方案。涉及到的包括登录、支付、分享等业务,都需要针对这些进行调整。

2)有限的测试机:

因为业务部门参与进来的很多,但工程样机十分有限。服务端和前端同学代码调整完毕后如何测试呢?这个是我们不得不考虑的一件事情。

新增一个鸿蒙终端,服务端调整后端代码,在测试和沙箱测试时,除了回归不要影响 Android 和 iOS 之外,还要能保证针对鸿蒙的兼容调整是有效的。鉴于鸿蒙测试机器十分有限,我们给 Server 同学提供了 Android 测试包,将 Android 测试包的终端 mock 成鸿蒙终端来供服务端测试接口,这样子测试下来十分高效。

针对前端同学:不能再向刚才那样做了,毕竟是用 Android 的 WebView。即便我们 WebView 的 UserAgent mock 成 Android 系统,使得通信和交互仍然走类似 Android 的策略,而这样并不能代表真实的鸿蒙 WebView 环境,因为在 Next 系统中整个 Native 和 Webview 的通信 Bridge 是全新的一套方案,且鸿蒙的 API 实现接口也都需要走鸿蒙侧来测试。针对这个情况,我们非常谨慎小心的将各个业务部门的参与进来的时间错开,尽力保证在有限测试机的情况下,每个业务轮转参与进来的时候都是有机器的。

5.3 多和华为伙伴进行沟通

这部分的经验,具有一定的时效性。后期商用版本发布之后,可能这样的沟通渠道、频次很难再有了。

为什么要多和华为伙伴时刻保持密切的沟通?有几个印象深刻的例子。

1)第一个例子:路由

鸿蒙关于页面跳转提供了两套解决方案,一套是页面路由 router,一套是组件导航 Navigation。前期我们在基建开发期间,采用的页面路由 router 方案,@zz/router 组件代码已经开发完毕了,但是到了开发 WebView 的 Hybrid 接口时,才意识到一个严重的问题,就是 router 提供的能力,并不能满足我们复杂的页面栈管理,譬如在页面栈中多个 WebView,我们需要关闭指定的 WebView 页面,router 提供的 API 能力是无法做到的。和华为沟通后才知道,官方是推荐 Navigation 来实现,且未来 router 方案不再演进。我们提出的复杂页面栈管理的能力,彼时 Navigation 支持的还不完整,但是伙伴告诉我们,他们会在 Navigation 上满足我们的需求。关闭页面栈中指定 index 或者 name 的页面,相信其他开发者也都会遇到,应该是一个普遍的需求。

基于这种情况,我们不得不迅速调整我们的路由组件,基于 Navigation 重新设计了一套路由方案,还好项目业务还没有开始大量开发,要改动的地方也不是很多,如果沟通再晚点,恐怕调整起来代价会相对更高点。此时的沟通,让我们少走了弯路,避免在 router 上走投无路死磕方案。

2)第二个例子:企业分发

企业分发通常用于企业内部测试、企业内部 App 等。Dev 证书和 iOS 的 Dev 证书类似,Provisioning Profile(p7b 文件)会有 100 台设备的限制。考虑到将来,转转也想依赖企业分发能力,可以在测试中采用企业签名打包来进行测试。虽说在当前阶段不是硬性和必要的,但是我们还有一个转转质检 App,这个 App 我们不能通过 AGC 后台上架华为市场,因为在质检中心,如果不走内部分发安装,那么我们将会面临着外网下载,会给质检中心的带宽带来很大的负载以及成本。

我们密切关注者企业分发能力的就绪时间,在今年的 5 月份,AGC 后台企业分发能力提供之后,立即进行了全流程处理,包括申请企业开发者、申请证书以及测试走通下载整个过程。这种情况下,通过及时交流,我们可以第一时间进行测试实践,有效降低或者避免了未来方案上的一些风险。

3)第三个例子:安全控件与系统 Picker

相信广大开发者今年刚开始介入 HarmonyOS Next 开发时,对于使用到的一些权限,如读取剪贴板,读取或者保存图片到相册等等这些 ACL(Access Control List)访问控制列表权限,都是通过在开发者后台勾选这些权限从而实现在应用中弹窗许可访问。但是在今年 6 月份的沟通中,我们获知后面要让开发者全部适配到安全控件方案。这些安全控件都是系统提供的选择器,使用之后,每次需要用户明确操作才行。

目前在 Android 和 iOS 中,如果想要在应用中上传一张照片,就需要同意该应用获得图库的访问权限,而带来的弊端就是,这个应用今后可随意访问你图库中的所有图片。相比之前的授权弹窗许可一次之后,可能造成的权限滥用,安全控件提升了用户对敏感权限的操作感知,算是 HarmonyOS Next 在保障用户隐私安全方面的一个亮点和优势。

这其中的核心理念便是从权限管控到数据管控。在 Android 和 iOS 原本的权限管控方案中,比如一旦给了通讯录权限,那么相当于把通讯录的钥匙给予了应用开发者,如果开发者违规使用,在用户不知情的读取整个通讯录,其实是不符合用户的隐私要求。而数据管控便是不会再把通讯录的钥匙给开发者,而是你要什么样的通讯录数据,那么你只能通过通讯录安全选择控件中来选择想要读取的通讯录,不再让应用随意获取整个通讯录数据。

关于安全控件我们进行了多次沟通,了解了安全控件在华为侧推进的节奏以及我们整改的期限时间等,另外我们也提出个别场景,安全控件还不足以满足诉求,譬如用户保存图片到相册,还没有对应的安全控件能力。这方面的沟通,会让我们及时的对 App 的隐私合规性做出优化调整,避免后面因为隐私权限问题而影响上架。

及时沟通对于了解 Bug 的解决情况,功能交付时间、华为伙伴的要求等都是很有必要的,因为这些都会影响到开发测试到上线的一个节奏。

6、鸿蒙NEXT上的WebView混合页面开发

6.1 概述

回到我们大前端来,得提一下大家关注的 WebView。在 HarmonyOS Next 中仍然沿用之前统一的 WebView 架构。

在 V1 版本中,需要做的核心工作包括:

  • 1)实现 WebView Core 层;
  • 2)JSBridge 层,新增实现 HarmonyOS Next 的 Bridge 通信;
  • 3)平移安全层能力;
  • 4)实现 Hybrid API 接口,也就是 Ability 层的能力。

需要特别提一下的是:HarmonyOS Next 使用的 Web 浏览器基于 ArkWeb(方舟Web内核),该内核基于 Chrome 114 版本定制,对于各种 CSS、HTML、JS 属性在各大浏览器中的兼容性情况可以使用 https://caniuse.com/#home 这个网站进行查询。

6.2 前期如何确定影响范围和制定方案

Ability 层的接口:转转的 WebView 历经多年的演进,Native 与 WebView 的交互 API 是有一定历史包袱的。我们不希望鸿蒙这次继续背着包袱前行,所以我们计划趁着这次前端业务兼容鸿蒙的机会,进行一波优化,丢弃一些已经计划不再使用的能力或者接口。比如老的半屏 WebView 方案,导航栏按钮功能设置方案、非统跳的页面跳转接口等。

但一个方案的确定要充分考虑客户端实现的难易程度以及前端大量业务侧统一修改的难度代价,需要做到尽可能的合理平衡。为了确定这点,我们根据线上最近一个月中URL 中接口调用的埋点日志,结合 URL 查询所属业务、开发测试负责人的内部接口,整理了一张巨大的二维矩阵表,通过在线表格的过滤、筛选等功能,可以非常直观的看到所有还在使用中的接口的业务调用分布情况,为我们评估方案改造工作量提供了重要的参考。

一个 Hybrid API 在鸿蒙上支持情况,分为下面几种情况。

a) 直接支持,前端无需修改:提供和 Android、iOS 一样的接口能力:

  • 1)功能对等:能力实现和 Andriod、iOS 一样;
  • 2)简化:比如浏览大图、奢侈品鉴定,暂时使用简版选图方案。

b) 推荐使用新方案:

  • 1)譬如导航栏相关按钮的能力、新半屏能力;
  • 2)如 enterChat 等等功能,使用统跳接口来实现跳转。

c) 不支持:

  • 1)业务下线:业务不再需要,下线处理;
  • 2)版本初期不考虑该功能;
  • 3)某端特定功能:为了解决某个问题,某端专门增加的一个 api 供使用;
  • 4)系统能力不支持:HarmonyOS Next 没有该项能力。

最终根据这些原则,我们确定下来 V1 版本中 WebView API 的需求范围、涉及业务方、改动方案。现在回想起来,当时我们做的这一步是非常有必要的,前期这些如果没有梳理清楚,后面就非常容易造成沟通混乱以及影响开发进度。

6.3 关于性能

转转前端的页面主要是 Web 形态,Hybrid 场景占据多数。在过去的几年中,我们围绕 Hybrid 形态,摸索出了一系列 Web 页面的优化方案。从基础的离线包,到复杂的预渲染、预请求等都有涉及。最终实现了 Hybrid 页面与 Native 页面在电商场景下,相差无几的体验。

目前鸿蒙在这块优化上,还都没来得及跟进这些优化手段。这个也是后面要继续建设的一个方向,最终要拉齐到和Android、iOS 一样的性能优化体验。

7、后续开发展望

首个版本上线,只是一个起点。

在业务上,我们将不断的继续追平 Android、iOS 中那些重要的模块和功能;

在开发工具体验和支持上,也逐渐补足缺失的能力,比如丰富的Native、WebView小工具能力,进一步提升客户端和前端在 HarmonyOS Next 下的开发体验。

在性能体验上,持续的关注和跟进性能问题,优化 WebView 以及 Native 的使用体验,提升 App 的流畅度和响应速度。

在创新上,我们将持续探索,将更多的 HarmonyOS Next 下的创新场景,如元服务、意图推荐等等融入到转转 App 中,提升用户的购物使用体验。

要做的事情很多,我们会在后续迭代中逐步完善起来这些能力,敬请期待。

8、相关资料

[1] 鸿蒙NEXT官方开发指南

[2] 一年撸完百万行代码,企业微信的全新鸿蒙NEXT客户端架构演进之路

[3] 鸿蒙NEXT如何保证应用安全:详解鸿蒙NEXT数字签名和证书机制

[4] 开源IM聊天程序HarmonyChat:基于鸿蒙NEXT的WebSocket协议

[5] 微信纯血鸿蒙版正式发布,295天走完微信14年技术之路!

[6] 即时通讯框架MobileIMSDK的鸿蒙NEXT端详细介绍

[7] 即时通讯框架MobileIMSDK的鸿蒙NEXT端开发者手册

[8] 转转平台IM系统架构设计与实践(一):整体架构设计

[9] 转转平台IM系统架构设计与实践(二):详细设计与实现

[10] Web端IM聊天消息该不该用浏览器本地存储?一文即懂

[11] 手把手教你使用网络编程抓包神器Wireshark

[12] 浅谈网页端IM技术及相关测试方法实践(包括WebSocket性能测试)


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

posted @ 2025-04-23 10:50 Jack Jiang 阅读(123) | 评论 (0)编辑 收藏

     摘要: 本文由企业微信客户端团队黄玮分享,原题“在流沙上筑城:企微鸿蒙开发演进”,下文进行了排版优化和内容修订。1、引言当企业微信团队在2024年启动鸿蒙Next版开发时,我们面对的是双重难题:1)在WXG小团队模式下,如何快速将数百万行级企业应用移植到全新操作系统?2)在鸿蒙API 还是Preview的初期,如何保持业务代码的稳定,在API快速更新的浪潮中岿然不动?DataLis...  阅读全文

posted @ 2025-04-15 11:22 Jack Jiang 阅读(136) | 评论 (0)编辑 收藏

     摘要: 本文由美团技术团队张晨分享,原题“鸿蒙应用签名实操及机制探究”,下文进行了排版优化和内容修订。1、引言华为鸿蒙单框架操作系统HarmonyOS NEXT已于2024年10月23日正式发布Release版。HarmonyOS NEXT仅支持鸿蒙原生应用,不再兼容安卓。本文对鸿蒙NEXT公开资料进行了深入分析和解读,梳理了鸿蒙单框架应用的签名机制,拆解每一步的实操过程和背后的实...  阅读全文

posted @ 2025-04-09 11:51 Jack Jiang 阅读(117) | 评论 (0)编辑 收藏

     摘要: 本文由阿里云望宸分享,原题“大模型推理主战场:什么才是通信协议标配?”,下文进行了排版优化和内容修订。1、引言DeepSeek 加速了模型平权,随之而来的是大模型推理需求的激增,大模型性能提升的主战场从训练转移到了推理。推理并发的提升,将催生计算、存储、网络、中间件、数据库等领域新的工程化需求。本文将分享 SSE 和 WebSocket 这两个AI大模型应用的标配网络通信协...  阅读全文

posted @ 2025-03-27 15:14 Jack Jiang 阅读(116) | 评论 (0)编辑 收藏

本文由夏冰软件cc分享,下文进行了排版和内容优化。

1、引言

本文接上篇《什么是IM系统的消息时序一致性?》,本篇将通俗易懂地讲解IM系统中的端到端加密原理,为了降低阅读门槛,相关的技术概念会提及但不深入展开

IM即时通讯系统的技术本质是“即时消息技术”,是互联网实时互动场景的底层架构,包括聊天、直播、在线客服等业务领域在内,所有需要实时互动、高实时性的场景,都需要用到IM技术。而为了让即时通讯更安全,高安全场景下的IM系统通常会使用端到端加密技术进行通讯加密。下面我们就来了解一下端到端加密技术在IM系统中的应用。

2、系列文章

  1. 零基础IM开发入门(一):什么是IM系统?
  2. 零基础IM开发入门(二):什么是IM系统的实时性?
  3. 零基础IM开发入门(三):什么是IM系统的可靠性?
  4. 零基础IM开发入门(四):什么是IM系统的消息时序一致性?
  5. 零基础IM开发入门(五):什么是IM系统的端到端加密?* 本文)》
  6. 《零基础IM开发入门(六):什么是IM系统的的心跳机制? (稍后发布)》
  7. 《零基础IM开发入门(七):如何理解并实现IM系统消息未读数? (稍后发布)》
  8. 《零基础IM开发入门(八):如何理解并实现IM系统的多端消息漫游? (稍后发布)》

3、网络通讯数据加密的3个层次

3.1 概述

一般的数据加密可以在通信的3个层次来实现:链路加密、节点加密和端到端加密。

3.2 链路加密

对于在两个网络节点间的某一次通信链路,链路加密能为网上传输的数据提供安全保证。对于链路加密(又称在线加密),所有消息在被传输之前进行加密,在每一个节点对接收到的消息进行解密,然后先使用下一个链路的密钥对消息进行加密,再进行传输。

在到达目的地之前,一条消息可能要经过许多通信链路的传输。由于在每一个中间传输节点消息均被解密后重新进行加密,因此,包括路由信息在内的链路上的所有数据均以密文形式出现,这样,链路加密就掩盖了被传输消息的源点与终点。由于填充技术的使用以及填充字符在不需要传输数据的情况下就可以进行加密,这使得消息的频率和长度特性得以掩盖,从而可以防止对通信业务进行分析。

相关文章推荐阅读:IM聊天系统安全手段之通信连接层加密技术》

3.3 节点加密

尽管节点加密能给网络数据提供较高的安全性,但它在操作方式上与链路加密是类似的:两者均在通信链路上为传输的消息提供安全性,都在中间节点先对消息进行解密,然后进行加密。因为要对所有传输的数据进行加密,所以加密过程对用户是透明的。然而,与链路加密不同,节点加密不允许消息在网络节点以明文形式存在,它先把收到的消息进行解密,然后采用另一个不同的密钥进行加密,这一过程是在节点上的一个安全模块中进行。

节点加密要求报头和路由信息以明文形式传输,以便中间节点能得到如何处理消息的信息,因此这种方法对于防止攻击者分析通信业务是脆弱的。

3.4 端到端加密

端到端加密允许数据在从源点到终点的传输过程中始终以密文形式存在。采用端到端加密(又称脱线加密或包加密),消息在被传输时到达终点之前不进行解密,因为消息在整个传輸过程中均受到保护,所以即使有节点被损坏也不会使消息泄露。

端到端加密系统的价格便宜些,并且与链路加密和节点加密相比更可靠,更容易设计、实现和维护。端到端加密还避免了其它加密系统所固有的同步问题,因为每个报文包均是独立被加密的,所以一个报文包所发生的传输错误不会影响后续的报文包。端到端加密系统通常不允许对消息的目的地址进行加密,这是囚为每一个消息所经过的节点都要用此地址来确定如何传输消息。由于这种加密方法不能掩盖被传输消息的源点与终点,因此它对于防止攻击者分析通信业务是脆弱的。

没有使用端到端加密时的通信原理图(各个环节都存在泄密的可能):

使用端到端加密后的通信原理图(除了发送者和接收者,其它环境都是密文状态):

4、IM系统中的端到端加密原理

在IM系统中,当用户A发送消息给用户B时,IM系统会生成一对公钥和私钥,并将公钥发送给用户B。用户A使用用户B的公钥对消息进行加密,然后将加密后的消息发送给用户B。

在用户B接收到消息后,使用自己的私钥对消息进行解密,从而获取明文内容。由于私钥只有用户B拥有,因此除了用户B之外,任何人都无法解密消息。

没有使用端到端加密时的聊天消息存在诸多风险:

使用了端到端加密后的聊天就安全多了:

5、IM系统使用端到端加密的好处

数据安全性:在IM系统中,端到端加密可以确保消息在传输过程中始终保持加密状态,防止黑客和第三方窃取用户的通信内容。

隐私保护:由于消息内容只有通信双方能够解密和阅读,即使是IM系统应用自身也无法获取明文内容。这意味着用户的隐私得到了最大程度的保护。

抗窃听:IM系统使用端到端加密技术,使得窃听者无法获取通信内容,从而有效防止了窃听行为的发生。

6、IM系统使用端到端加密的意义

由于在数据传输到服务器之后,任何有权访问此服务器的人,包括员工、供应商及其他有关人员(甚至是黑客),都有可能读取到用户的数据。

所以,使用端到端加密技术主要有以下意义:

1)保护个人隐私:在信息时代,个人隐私面临着越来越大的威胁。在IM系统中使用端到端加密可以有效保护了用户的通信内容,确保个人隐私不被侵犯。

2)防止数据泄露:许多用户在社交软件中分享了大量的个人信息和敏感数据。而IM系统中的端到端加密就可以确保这些数据在传输过程中不会被窃取,从而避免了数据泄露的风险。

3)抵御网络攻击:黑客和网络犯罪分子经常利用网络漏洞和弱点来攻击用户的通信。IM系统中的端到端加密可以有效防止这些攻击,保护用户的通信安全。

4)维护社交关系:人们越来越依赖社交应用来保持联系和交流。IM系统使用端到端加密可以使得用户能够放心地分享私密信息,维护社交关系的同时保护了个人隐私。

7、IM系统使用端到端加密的不足

通讯效率低:由于端对端加密需要对通讯数据进行加密和解密,因此可能会导致通信效率较低。

需双向支持:端对端加密需要发送方和接收方都需要支持该技术,否则就将无法实现端对端加密通信。

安全性问题:虽然端对端加密可以防止中间人攻击,但如果黑客能够获得了私钥或公钥,那么他们也能够轻易地获取到通信数据。

8、延伸阅读

本文内容主要是面向即时通讯技术的初学者以及产品经理,所以相关的技术概念都没有深入探讨,感光趣的可以继续深入阅读我整理的以下几篇资料。

  1. IM聊天系统安全手段之通信连接层加密技术
  2. IM聊天系统安全手段之传输内容端到端加密技术
  3. 移动端安全通信的利器——端到端加密(E2EE)技术详解
  4. 简述实时音视频聊天中端到端加密(E2EE)的工作原理

9、参考资料

[1] 网络编程懒人入门(三):快速理解TCP协议一篇就够

[2] 即时通讯初学者必知必会的20个网络编程和通信安全知识点

[3] 为什么要用HTTPS?深入浅出,探密短连接的安全性

[4] 理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)

[5] 微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解

[6] 移动端安全通信的利器——端到端加密(E2EE)技术详解

[7] 常用加解密算法与通讯安全讲解

[8] 通俗易懂:一篇掌握即时通讯的消息传输安全原理

[9] 基于Netty的IM聊天加密技术学习:一文理清常见的加密概念、术语等

[10] 手把手教你为基于Netty的IM生成自签名SSL/TLS证书

[11] 微信技术分享:揭秘微信后台安全特征数据仓库的架构设计

[12] 即时通讯初学者必知必会的20个网络编程和通信安全知识点

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

posted @ 2025-03-20 11:11 Jack Jiang 阅读(86) | 评论 (0)编辑 收藏

     摘要: 本文由vivo互联网服务器团队Cai Linfeng分享,来自公众号“ vivo互联网技术”,原题“百万级群聊的设计实践”,下文进行了排版优化和内容修订。1、引言现在IM群聊产品多种多样,有国民级的微信、QQ,企业级的钉钉、飞书,还有许多公司内部的IM工具,这些都是以客户端为主要载体。而且群聊人数通常都是有限制,微信正常群人数上限是500,QQ200...  阅读全文

posted @ 2025-03-13 13:36 Jack Jiang 阅读(112) | 评论 (0)编辑 收藏

本文由B端技术中心资深开发工程师马家忆分享,原题“B站在实时音视频技术领域的探索与实践”,下文进行了排版和内容优化。

1、引言

直播行业从传统的娱乐直播发展到教育直播、电商直播等形式,产生了很多新的玩法。传统的直播是一位主播展示才艺,观众通过弹幕、送礼物等方式进行互动。随着网络质量不断地提高,用户也对直播平台产生的新的要求,实时互动直播的场景就出现了,观众可以同时观看多位主播之间互动的画面,让直播间的气氛更好。B站直播的连麦PK、视频连线业务就提供了这个能力。主播看到的是对方主播实时的流(延迟400ms以内),而观众看到的是“准实时”的流(延迟2~5s左右)。

本文讲述搭建这样一套最新流行的实时视频直播系统需要了解的背景知识以及系统的整体架构,希望对大家有帮助。

2、系列文章

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

视频直播技术干货(一):揭秘百万级粉丝互动的Facebook实时视频直播

视频直播技术干货(二):P2P技术如何将实时视频直播带宽降低75%?

视频直播技术干货(三):实时直播答题系统的实现思路与技术难点分享

视频直播技术干货(四):首次披露快手是如何做到百万观众同场看直播仍能秒开且不卡顿的?

视频直播技术干货(五):七牛云使用QUIC协议实现实时视频直播0卡顿

视频直播技术干货(六):新浪微博实时直播答题的百万高并发架构实践

视频直播技术干货(七):实时视频直播首屏耗时400ms内的优化实践

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

视频直播技术干货(九):千万级直播系统后端架构设计的方方面面

视频直播技术干货(十):一文读懂主流视频直播系统的推拉流架构、传输协议等

视频直播技术干货(十一):超低延时视频直播技术的演进之路

视频直播技术干货(十二):从入门到放弃,快速学习Android端直播技术

视频直播技术干货(十三):B站实时视频直播技术实践和音视频知识入门》(* 本文

3、关于作者

马家忆:B端技术中心资深开发工程师。

4、实时音视频关键技术概述

从0到1搭建一套实时音视频系统并支撑现有的业务,如果没有接触过这方面的东西会感觉无从下手。

我们可以看到,1996年IETF就推出了RTP协议用于实时音视频传输,2011年Google推出了WebRTC用于网页端实时音视频通话(见《了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化》)。

从这些现有的协议和项目中,我们可以发现实时音视频技术的关键点,评估自身现有的基础组件支持情况并结合业务场景寻找适合自己的解决方案。

5、关键技术1:传输协议

RTP协议(Real-time Transport Protocol)定义了在互联网上传输实时音视频数据的标准格式,属于应用层协议。RFC 3550描述RTP协议的传输层主要使用UDP,RFC 4571描述了RTP协议的TCP传输方式。

在我们的实时音视频场景中应当优先选择UDP,理由如下:

1)TCP保证数据流的可靠性和顺序性。TCP的超时重传策略为了保证通用和公平,相对比较保守,重传超时时间(RTO)可能会变的很大。假如中途丢失一个包,后续的包即使先到达也要缓存起来等待重传完成以后才能送到应用层。在网络状况不佳的情况下,使用TCP传输会产生较大的延迟;

2)UDP允许数据包丢失、乱序和重复。即使数据丢失也不会阻塞接收缓冲区等待重传,这就为实时性提供了保障。在上层的RTP协议中,协议头部包含了时间戳和序列号,可以对数据包进行重排和丢弃,解决了乱序和重复的问题。如果接收端监测到丢包,并且丢失的包是必要的且无法恢复,则发送NACK消息通知发送端重传(下一节会详细探讨这个话题)。

UDP虽然在低延迟领域上有压倒性的优势,但是用户侧有可能存在防火墙拦截所有的UDP包。考虑到在网络环境足够好的情况下使用TCP也能达到不错的效果,因此我们做了一个降级策略,优先使用UDP,当且仅当UDP不通的时候使用TCP。

6、关键技术2:丢包补偿

前面讲到我们的传输层协议优先选择UDP,那么就需要引入一些机制解决丢包问题。

前向纠错FEC(Forward Error Correction)指的是发送端发送原始数据的同时附加部分冗余的信息,如果接收端检测到原始数据丢失则尝试使用冗余的信息进行恢复。发送端发送n个数据包,同时根据原始数据生成k个冗余的数据包,将n+k个数据包发送出去,接收端只要收到至少n个数据包就可以得到全部的原始数据。

FEC算法的关键在于异或。异或(Exclusive OR)是一个数学运算符,数学符号为“⊕”,两边数值转换成二进制按位运算,相同时为0,不同时为1。

以一阶冗余算法为例,n个数据包生成1个冗余包,发送n+1个数据包。我们发送三个数值分别为a、b、c,生成冗余数据x=a ⊕b ⊕ c一起发送。假如数值b在传输中丢失了,计算a ⊕c ⊕ x即可得到b。

在实际应用中,FEC没有这么简单,WebRTC实现了UlpFEC和FlexFEC,UlpFEC可以针对数据包的重要程度实施不同程度的保护以充分利用带宽,FlexFEC还支持对列做冗余,同时WebRTC默认的音频编码器Opus本身就支持FEC。

前向纠错适合少量随机丢包的场景,可以无视网络延迟时间,但是增加了带宽消耗。

后向纠错包括ARQ(Automatic Repeat Request)和PLC(Packet Loss Concealment)。ARQ指的是接收端检测到数据丢失的时候发送NACK报文请求发送端重传,适合突发大量丢包的场景,没有额外的带宽消耗,但是时效性取决于RTT,如果存在很多接收端还要考虑避免NACK风暴造成雪崩。PLC用于音频,当数据缺失时使用模型根据前后数据预测丢失的数据。

总之,前向纠错和后向纠错各有优缺点,需要搭配使用。

7、关键技术3:流量控制

流量控制指的是根据网络状况的波动估算可用带宽,根据带宽的变化自动调节音视频码率和发送速率。当网络质量变差的时候迅速降低数据量以确保实时性,网络较好时则慢慢提升数据量带来更清晰的画面。在WebRTC中提供了优秀的Google Congestion Control算法,包括基于延迟的评估和基于丢包率的评估,取两种评估方式的最小值作为目标带宽通知编码器和数据发送模块。

基于延迟的评估算法包括Transport-CC和Goog-REMB,目前最新版的WebRTC默认使用的是Transport-CC。Transport-CC在发送端进行带宽评估,接收端通过TransportFeedback RTCP包向发送端反馈每个RTP包的到达时间,发送端在一个时间窗口内计算每个RTP包到达时间与发送时间之差,通过Trendline滤波器处理后预测网络状况。假设我们当前处于Hold状态,如果检测到网络状态为OverUse,此时应该减小数据量,变更为Decrease状态;如果检测到网络状态为Normal,此时可以尝试增加数据量,变更为Increase状态。

基于丢包的评估算法是当网络突发大量丢包时的兜底策略:

  • 1)如果丢包率在2%以下的时候说明网络质量好,目标带宽增加8%;
  • 2)如果丢包率在在2%~10%说明当前发送数据的带宽和网络质量相匹配可以保持不变;
  • 3)如果丢包率大于10%说明网络质量差,目标带宽减小到(1-丢包率*0.5)* 当前带宽。

8、关键技术4:数据缓冲

如果我们只考虑实时性,那么收到数据就立刻解码并渲染必然是最好的选择,但是网络并不稳定,延迟、乱序、丢包、重复包都有可能发生。如果采用上面的策略,音频可能因为网络的抖动变的断断续续,视频可能因为丢包导致缺少参考帧从而出现黑屏或花屏,所以有必要引入一个缓冲区,增加一点可以接受的延迟来保证用户体验。

在WebRTC中,视频包会被放入JitterBuffer模块进行处理,JitterBuffer会进行视频包的排序、组装成完整的帧、确保参考帧有效,然后把数据送到解码器。同时,根据网络状况自适应地调节缓冲区的长度。音频包会被放入NetEQ中,它维护了音频的缓冲区,同时负责将音频同步到视频。我们做播放器一般都是以音频的时间为基准同步视频,但是WebRTC刚好相反,它是以视频为基准的。当音频数据堆积的时候加速音频播放,音频数据不足的时候降低速度把音频拉长。

9、关键技术5:回声消除

在语音通话的场景中,麦克风采集到的声音发送给远端,远端的扬声器播放出来以后又被远端的麦克风采集到这个声音并传送回来,这样讲话的人会感觉到有回声,影响体验。

WebRTC提供了回声消除算法AEC,时延估计(Delay Estimation)模块找到扬声器信号和麦克风信号的时延,线性自适应滤波器(Linear Adaptive Filter)参考扬声器信号估算回声信号并将其剪去,最后通过非线性处理(Nonlinear Processing)模块消除残留的回声。

10、关键技术6:最优路径

实时音视频对网络的要求非常高,如果通话双方距离很远,那么通话质量是很难保证的。城市A的设备给城市D的设备发送数据,直接发送未必是最优的选择,从城市B和城市C中转一下有可能更快。

理想的解决方案是在全球部署加速节点,用户就近接入。根据加速节点之间的实时网络质量探测数据,找到一条最优传输路径,避开网络的拥堵。

11、开源音视频框架WebRTC简述

刚才介绍了实时音视频系统实现过程中所需的关键技术,多次提到了WebRTC。显然,对于绝大多数团队来说,这些内容如果全部自主研发几乎是不可能的事情,而我们站在WebRTC的基础上去设计自己的系统是较为明智的选择。

WebRTC的代码非常复杂,想要把它搞清楚是一件非常困难的任务,我第一次看到WebRTC的代码根本就不知道从哪里下手。

幸运的是,WebRTC官方提供了架构图,可以先帮助我们对它进行一个宏观的了解。

WebRTC整体架构大概可以分为接口层、会话层、引擎层和设备I/O层:

1)接口层包括Web API和WebRTC C++ API,Web API给Web开发者提供了JavaScript接口,这样Web端就具备了接入WebRTC的能力;WebRTC C++ API面向的是浏览器开发者,让浏览器开发商具备集成WebRTC的能力。当然,WebRTC C++ API也可以用于Native客户端接入;

2)会话层主要包含信令相关的逻辑,比如媒体协商,P2P连接管理等;

3)引擎层是WebRTC最核心的功能,包括音频引擎、视频引擎和传输模块。音频引擎包含音频编解码器(Opus)、NetEQ和著名的3A(回声消除、自动增益、降噪)算法;视频引擎包括视频编解码器(VP8、VP9、H264)、JitterBufer和图像增强(降噪)算法;传输模块包含SRTP、多路复用和P2P模块;

4)设备I/O层主要和硬件交互,包括音视频采集和渲染,以及网络I/O。

上面一节描述的实时音视频关键技术中,WebRTC实现了除“最优路径”之外的全部内容。WebRTC几乎每个模块都是可以按需替换的,便于我们增加定制的内容。我们可以根据实际需求决定如何使用WebRTC,Native客户端可以通PeerConnection接口接入,服务端拿到RTP/RTCP包以后完全可以直接调用引擎层处理拿到最终的YUV和PCM数据,甚至只把WebRTC内部模块抠出来用在自己的系统上也是没问题的。

更多相关资料可阅读:

  1. 零基础入门:基于开源WebRTC,从0到1实现实时音视频聊天功能
  2. 实时音视频入门学习:开源工程WebRTC的技术原理和使用浅析
  3. 零基础快速入门WebRTC:基本概念、关键技术、与WebSocket的区别等

12、B站视频直播系统架构

我们回到B站的连麦PK业务场景,两位主播进行互动PK,同时大量观众在直播间观看PK的过程。

显然,两位主播通话要求低延迟,必须使用实时音视频系统交互;而观众观看直播的延迟要求相对没那么严格,可以采取传统直播的模式,通过RTMP或者SRT推流到CDN,用户从CDN拉流。

然后我们要思考两个问题。

12.1 问题1:主播之间的音视频通话是采用P2P还是服务器中转?

首先对P2P和服务器中转两种方案做个对比:

对于P2P方案来说,只需要部署STUN和TURN服务器,如果成功建立P2P连接那么后续媒体数据传输就不需要经过服务器,所以具有成本优势。然而,P2P的缺点也很明显,如果打洞失败还是需要TURN服务器中转,且建立连接的过程耗时较高,用户之间距离较远的情况下网络质量不可控,而且现有的第三方网络加速服务基本上都不支持P2P。

我们这里选择服务器中转的方案,因为实时音视频本身对网络的要求比较高,不会设置过高的码率,所以网络传输的数据量是可控的,成本能够接受。而且我们的实时音视频数据要对接AI审核,还要实现服务器混流,这是P2P方案做不到的。

12.2 问题2:推送给观众的流到CDN,这个工作放在主播客户端还是服务器?

两位主播PK对应的是两路流,观众只从CDN拉一路流,所以必须有个地方做混流。这里的混流指的是把两位主播的视频进行拼接、音频进行混合,然后打包成一路流。主播客户端能收到对方的流,可以和自己的流做混流;在前面提到的服务器中转方案中,服务器有双方的流,同样也可以完成混流。

我们先对比一下两种方案的优劣:

服务器进行混流需要先解码再编码,这需要消耗大量计算资源,所以成本很高;主播客户端进行混流需要额外增加一路流的编码和上传,对设备性能和上行带宽来说也是很大的挑战。

主播客户端需要等待服务器把对方的流发送过来才能混流,所以从延迟的角度来看服务器混流稍微占据优势,不过这个延迟相比CDN的延迟可以忽略不计。如果后期对通话质量要求变高,主播的设备性能和上行带宽跟不上,我们可以很容易增加服务器来扩展计算资源和带宽,所以在可扩展性方面服务器混流胜出。

另外,当主播从正常直播切换到连麦PK状态的时候,采用服务器混流必须先把直播的流停掉再由服务器接管,中间的时间差可能会产生卡顿或黑屏影响观众体验,而主播客户端混流可以做到无缝切换。

所以,这两种方案各有优缺点,我们采取折衷的办法:如果主播的设备负载较低且上行带宽比较充足,优先采用主播客户端混流的方式,否则降级为服务器混流。

12.3 开始架构设计

上面两个问题分析清楚了,就可以开始设计了。

这是我们的系统整体架构:

rtc-service主要提供信令、频道管理、主播管理、公有云上媒体服务器集群的健康检查和节点分配、同步主播状态到业务服务器、记录通话流水。

rtc-job是对rtc-service的补充,定期检查当前在线主播的状态,发现主播异常下线时触发兜底逻辑。

rtc-router负责收发主播的音视频数据。主播可以收到同一个频道内其他人的音视频流。如果需要服务器混流,则访问注册中心并采用Google的有界负载一致性哈希算法(Consistent Hashing with Bounded Loads)选取rtc-mixer节点,并往对应节点推送主播的音视频流。

rtc-mixer负责混流,根据需求拼接画面和混音,然后推送到CDN,观众通过CDN拉流。

主播的客户端并没有直接向rtc-router发送数据,而是通过第三方的四层加速网络转发。我们前面提到了“最优路径”的概念,第三方的四层加速服务可以让用户接入最近的加速节点,然后寻找最优路径把数据转发到我们的公有云节点。客户端只能看到第三方的加速节点IP,看不到我们公有云媒体服务器的IP,这在一定程度上可以防止服务器遭到攻击;其次,我们可以在保证异地多活的前提下让公有云集群相对比较集中,节省成本。

服务的可用性和容错性也是一个很重要的问题,假如在主播PK即将胜利的时刻服务出现故障,弹出"PK异常终止请重新再来",这很令人绝望。我们不仅要保证服务可用,还要尽最大可能保证服务出现故障时减小对用户的影响,让流程能够走下去。接下来讨论系统中每个风险模块为了实现这个目标所采取的措施:

四层加速网络故障。这个属于第三方厂商提供的服务,每个厂商提供的接入方式大同小异,基本上就是附加的header有差别,所以同时对接多家厂商对客户端来说是很容易做到的。客户端进行连通性检查,只要存在至少一家厂商的服务可用,就不会影响业务。

公有云上的rtc-router和rtc-mixer故障。在公有云上部署服务,尽量要多厂商、多区域部署,防止单机房整体宕机。我们同样准备了多个集群,每个集群都部署了多台rtc-router、rtc-mixer和ZooKeeper,单个集群可以独立工作,如果单个集群不可用或者负载达到上限则会被熔断。核心机房的rtc-service会对公有云上的集群进行健康检查,如果rtc-router宕机,rtc-service会通过信令通道通知客户端切换到同集群中其他服务器,当同集群没有可用机器时则切换集群。如果rtc-mixer宕机,rtc-router会通过ZooKeeper重新选择一台接管混流任务。

核心机房的rtc-service和rtc-job故障。这部分内容和B站大部分核心服务部署在同样的集群,复用了B站比较成熟的高可用架构。这部分内容可以参考其他文章,这里不再赘述。

13、本文小结

如果我们把实时音视频技术比作一座富丽堂皇的城池,这篇文章只能带领大家来到城门口。我们也不会停止探索的脚步。希望大家读到这里能够有所收获,如有疏漏,欢迎批评指正。

14、参考资料

[1] 实时语音通讯的回音及回音消除概述

[2] 实时语音通讯的回音消除技术详解

[3] 实时语音通讯丢包补偿技术详解

[4] 零基础,史上最通俗视频编码技术入门

[5] IM实时音视频聊天时的回声消除技术详解

[6] 学习RFC3550:RTP/RTCP实时传输协议基础知识

[7] 基于RTMP数据传输协议的实时流媒体技术研究(论文全文)

[8] 爱奇艺技术分享:轻松诙谐,讲解视频编解码技术的过去、现在和将来

[9] 零基础入门:实时音视频技术基础知识全面盘点

[10] 实时音视频面视必备:快速掌握11个视频技术相关的基础概念

[11] 零基础入门:基于开源WebRTC,从0到1实现实时音视频聊天功能

[12] 实时音视频入门学习:开源工程WebRTC的技术原理和使用浅析

[13] 零基础快速入门WebRTC:基本概念、关键技术、与WebSocket的区别等

[14] 移动端实时音视频直播技术详解(五):推流和传输

[15] 移动端实时音视频直播技术详解(六):延迟优化

[16] 实时视频直播客户端技术盘点:Native、html5、WebRTC、微信小程序

[17] 浅谈开发实时视频直播平台的技术要点

[18] 视频直播技术干货:一文读懂主流视频直播系统的推拉流架构、传输协议等

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

posted @ 2025-03-06 11:46 Jack Jiang 阅读(86) | 评论 (0)编辑 收藏

仅列出标题
共53页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last 
Jack Jiang的 Mail: jb2011@163.com, 联系QQ: 413980957, 微信: hellojackjiang