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

93次阅读

共计 6757 个字符,预计需要花费 17 分钟才能阅读完成。

本文由阿里闲鱼技术团队祈晴分享,本次有订正和改变,感激作者的技术分享。

1、内容概述

本文总结了阿里闲鱼技术团队应用 Flutter 在对闲鱼 IM 进行挪动端跨端革新过程中的技术实际等,文中比照了传统 Native 与当初大热的 Flutter 跨端计划在一些次要技术实现上的差别,以及针对 Flutter 技术特点的具体技术实现,值得同样筹备应用 Flutter 开发 IM 的技术同行们借鉴和参考。

学习交换:

  • 即时通讯 / 推送技术开发交换 5 群:215477170 [举荐]
  • 挪动端 IM 开发入门文章:《新手入门一篇就够:从零开发挪动端 IM》
  • 开源 IM 框架源码:https://github.com/JackJiang2…

(本文同步公布于:http://www.52im.net/thread-36…)

2、闲鱼 IM 现状

闲鱼 IM 的挪动端框架构建于 2016 至 2017 年间,期间通过屡次迭代降级导致历史包袱累积多,前面又经验 IM 界面的 Flutter 化,从而造成了客户端架构更加简单。

从开发层面总结闲鱼 IM 挪动端以后架构次要存在如下几个问题:

  • 1)研发效率较低:以后架构波及到 Android/iOS 双端的逻辑代码以及 Flutter 的 UI 代码,定位问题往往只能从 Flutter UI 表相倒查到 Native 逻辑层;
  • 2)架构档次较差:架构设计上分层不清晰,业务逻辑夹杂在外围的逻辑层以致代码变更危险大;
  • 3)性能测试略差:外围数据源存储 Native 内存,需经 Flutter Plugin 将数据源序列化上抛 Flutter 侧,在大批量数据源状况下性能体现较差。

从产品层面总结闲鱼 IM 挪动端以后架构的次要问题如下:

  • 1)定位问题艰难:线上舆情反馈千奇百怪,测试始终无奈复现相干场景,因而很多时候只能靠景象猜想实质;
  • 2)疑难杂症较多:架构的不稳定性造成呈现的问题重复呈现,以后疑难杂症次要包含未读红点计数、iPhone5C 低端机以及多媒体发送等多个问题;
  • 3)问题差异性大:Android 和 iOS 两端逻辑代码差别大,包含埋点逻辑都不尽相同,排查问题本源时双端都会有不同根因,解决方案也不雷同。

3、业界的挪动端跨端计划

为解决以后 IM 的技术痛点,闲鱼往年特起对于 IM 架构降级我的项目,重在解决客户端中 Andriod 和 iOS 双端一致性的痛点,初步构想计划就是实现跨端对立的 Android/iOS 逻辑架构。

在以后行业内跨端计划可初步归类如下图架构:

在 GUI 层面的跨端计划有 Weex、ReactNative、H5、Uni-APP 等,其内存模型大多须要通过桥接到 Native 模式存储。

在逻辑层面的跨端计划大抵有 C /C++ 等与虚拟机无关语言实现跨端,当然汇编语言也可行。

此外有两个独立于上述体系之外的架构就是 Flutter 和 KMM(谷歌基于 Kotlin 实现相似 Flutter 架构),其中 Flutter 运行特定 DartVM,将内存数据挂载其本身的 isolate 中。

思考闲鱼是 Flutter 的前沿探索者,计划上优先应用 Flutter。然而 Flutter 的 isolate 更像一个过程的概念(底层实现非应用过程模式),相比 Android,同一过程场景中,Android 的 Dalvik 虚拟机多个线程运行共享一个内存 Heap,而 DartVM 的 Isolate 运行隔离各自的 Heap,因此 isolate 之间通信形式比拟繁琐(需通过序列化反序列化过程)。

整个模型如下图所示:

若按官网混合架构实现 Flutter 利用,开启多个 FlutterAcitivty/FlutterController,底层会生成多个 Engine,对应会存在多个 isolate,而 isolate 通信相似于过程通信(相似 socket 或 AIDL),这里借鉴闲鱼 FlutterBoost 的设计理念,FlutterIM 架构将多个页面的 Engine 共享,则内存模型就人造反对共享读取。

原理图如下:

4、闲鱼 IM 基于 Flutter 的架构设计

4.1 新老架构比照
如下图所示:是一个老架构计划,其外围问题次要集中于 Native 逻辑形象差,其中逻辑层面还设计到多线程并发使得问题倍增,Android/iOS/Flutter 交互繁冗,开发保护老本高,核心层耦合较为重大,无插拔式概念.

思考到历史架构的问题,演进如下新架构设计:

如上图所示,架构从上至下顺次为:

  • 1)业务层;
  • 2)散发层;
  • 3)逻辑层;
  • 4)数据源层。

数据源层来源于推送或网络申请,其封装于 Native 层,通过 Flutter 插件将音讯协定数据上抛到 Flutter 侧的外围逻辑层,解决实现后变成 Flutter DB 的 Enitity 实体,实体中挂载一些音讯协定实体。

外围逻辑层将繁冗数据扁平化打包挂载到散发层中的会话内存模型数据或音讯内存模型数据,最初通过观察者模式的订阅散发到业务逻辑中。

Flutter IM 重点集中革新逻辑层和散发层,将 IM 外围逻辑和业务层面数据模型进行封装隔离,外围逻辑层和数据库交互后将数据封装到散发层的 moduleData 中,通过订阅形式散发到业务层数据模型中。

此外在 IM 模型中 DB 也是重点依赖的,集体对 DB 数据库治理进行全面封装解,实现一种轻量级,性能佳的 Flutter DB 治理框架。

4.2 DB 存储模型
Flutter IM 架构的 DB 存储依赖数据库插件,目前支流插件是 Sqflite。

其存储模型如下:

根据上图 Sqflite 插件的 DB 存储模型会有 2 个期待队列:

  • 一个是 Flutter 层同步执行队列;
  • 一个是 Native 层的线程执行队列。

其 Android 实现机制是 HandlerThread,因而 Query/Save 读写在会同一线程队列中,导致响应速度慢,容易造成 DB SQL 沉积,此外缺失缓存模型。

于是集体定制如下改良计划:

Flutter 侧通过表的主键设计查问时候会优先从 Entity Cache 层去获取,若缓存不存在,则通过 Sqflite 插件查问。

同时革新 Sqflite 插件成反对 sync/Async 同步异步两种形式操作,对应到 Native 侧也会有同步线程队列和异步线程队列,保证数据吞吐率。然而这里倡议查问应用异步,存储应用同步更稳当,次要怕呈现多个雷同的数据元 model 同一时间进入异步线程池中,存储先后顺序无奈无效的保障。

4.3 ORM 数据库计划
IM 架构重度依赖 DB 数据库,而以后业界还没有一个齐备的数据库 ORM 治理计划,参考了 Android 的 OrmLite/GreenDao,集体自行设计一套 Flutter ORM 数据库治理计划。

其核心思想如下:

因为 Flutter 不反对反射,因而无奈间接像 Android 的开源数据库形式操作,但可通过 APT 形式,将 Entity 和 Orm Entity 绑定于一身,操作 OrmEntity 即操作 Entity,整个代码格调设计也和 OrmLite 极其类似。

参考代码如下:

4.4 IM 内存数据模型
基于 Flutter 的 IM 挪动端架构在内存数据模型次要划分为会话和音讯两个颗粒度:

1)会话内存数据模型交托于 SessionModuleData:会话内存数据有一个根节点 RootNotice,而后其挂载 PSessionMessageNotice(这里 PSessionMessageNotice 是 ORM 映射的会话 DB 表模型)子节点汇合。
2)音讯内存数据模型交托于 MessageModuleData:音讯内存数据会有一个 MessageConatiner 容器治理,其外部挂载此会话中的 PMessage(PMessage 是 ORM 映射的音讯 DB 表模型)音讯汇合。
根据上一章节,PSessionMessageNotice 设计了一个 OrmEnitity Cache,思考到 IM 中会话数是无限的,因而 PSessionMessageNotice 都是间接缓存到 Cache 中。

这种做法的益处是各地去拿会话数据元时候都是缓存中同一个对象,容易保障多次重复读写的数据一致性。而 PSessionMessageNotice 思考到其数量能够有限多的特殊性,因而这里将其挂载到 MessageContainer 的内存治理中,在退出会话的时机会校验容器中 PMessage 汇合的数量,适当缩容能够缩小内存开销。

模型如下图所示:

4.5 状态治理计划
基于 Flutter 的 IM 挪动端架构状态治理计划比较简单,对数据源 Session/Message 维度应用观察者模式的订阅散发形式实现,架构相似于 EventBus 模式,页面级的状态治理无论应用 fish-redux、scopeModel 或者 provider 简直影响面不大,外围还是需保留一种插拔式形象更重要。

架构如下图:

4.6 IM 同步模型计划
以后现状的音讯同步模型:

如上图所示是,模型中存在 ACCS Thread/Main Thread/Region Thread 等多线程并发场景,导致易呈现多线程高并发的问题。

native 的推送和网络申请同步的隔离计划通过 Lock 的锁机制,并且通过队列降频等形式解决,流程繁琐且易出错。整体通过 Region Version Gap 去判断是否有域空洞,进而执行域同步补充数据。

改良的同步模型如下:

如上图所示,在 Flutter 侧人造没多线程场景,通过一种标记位的转化同步异步实现相似 Handler 音讯队列,架构清晰简洁了很多,防止锁带来的开销以及同步问题。

5、本次革新停顿以及性能比照

1)针对架构层面:

在基于 Flutter 的 IM 架构中,重点将双端逻辑差异性对立成同一份 Dart 代码,齐全磨平 Android/iOS 的代码差异性带来的问题。

带来的益处很显著:

  • 1)升高开发保护、测试回归、视觉验收的一半老本,极大进步研发效率;
  • 2)架构上进行重构分层,实现一种解耦合,插拔式的 IM 架构;
  • 3)同时 Native 到 Flutter 侧的大量数据上抛序列化过程革新程 Flutter 援用传递,解决极限测试场景下的私聊卡顿问题。

2)针对线上舆情:

  • 1)补齐 UT 和 TLog 的团体日志形式做到可追踪,可排查;
  • 2)针对于很多现存的疑难杂症重点集中专项解决,比方 iphone5C 的架构在 Flutter 侧统一规划;
  • 3)未读红点计数等问题也在架构模型降级中修复;
  • 4)此外多媒体音视频发送模块进行革新降级。

3)性能数据比照:

当 IM 架构的逻辑层和 UI 层都切换成 Flutter 后,和原先架构模式初步比照,整体内存水位持平。

其中:

1)私聊场景下小米 9 测试构造内存降落 40M,功耗升高 4mah,CPU 升高 1%;
2)极限测试场景下新架构内存数据相比于旧架构有一个较为显著的改观(次要因为两个界面都应用 Flutter 场景下,页面切换的开销升高很多)。

6、将来瞻望

JS 跨端不平安,C++ 跨端老本有点高,Flutter 会是一个较好抉择。彼时闲鱼 FlutterIM 架构降级基本目标从来不是因 Flutter 而 Flutter,是因为历史包袱的沉重,代码层面的保护老本高,新业务的扩展性差,人力配比不协调以及疑难杂症的舆情继续反馈等等因素造成咱们不得不去摸索新计划。

通过闲鱼 IM 超简单业务场景验证 Flutter 模式的逻辑跨端可行性,闲鱼在 Flutter 路上会始终放弃前沿摸索,最初能反馈到生态圈。

总结一句话,摸索过程在于你敢于迈出第一步,前面才会一直惊喜发现。

(原文链接:点此进入,本次有订正和改变)

附录:更多文章汇总

[1] 更多阿里团队的文章分享:
《阿里钉钉技术分享:企业级 IM 王者——钉钉在后端架构上的过人之处》
《古代 IM 零碎中聊天音讯的同步和存储计划探讨》
《阿里技术分享:深度揭秘阿里数据库技术计划的 10 年变迁史》
《阿里技术分享:阿里自研金融级数据库 OceanBase 的艰苦成长之路》
《来自阿里 OpenIM:打造安全可靠即时通讯服务的技术实际分享》
《钉钉——基于 IM 技术的新一代企业 OA 平台的技术挑战(视频 +PPT) [附件下载]》
《阿里技术结晶:《阿里巴巴 Java 开发手册(规约)- 华山版》[附件下载]》
《重磅公布:《阿里巴巴 Android 开发手册(规约)》[附件下载]》
《作者谈《阿里巴巴 Java 开发手册(规约)》背地的故事》
《《阿里巴巴 Android 开发手册(规约)》背地的故事》
《干了这碗鸡汤:从理发店小弟到阿里 P10 技术大牛》
《揭秘阿里、腾讯、华为、百度的职级和薪酬体系》
《淘宝技术分享:手淘亿级挪动端接入层网关的技术演进之路》
《难得干货,揭秘支付宝的 2 维码扫码技术优化实际之路》
《淘宝直播技术干货:高清、低延时的实时视频直播技术解密》
《阿里技术分享:电商 IM 音讯平台,在群聊、直播场景下的技术实际》
《阿里技术分享:闲鱼 IM 基于 Flutter 的挪动端跨端革新实际》
[2] 更多 IM 开发综合文章:
《新手入门一篇就够:从零开发挪动端 IM》
《挪动端 IM 开发者必读(一):通俗易懂,了解挪动网络的“弱”和“慢”》
《挪动端 IM 开发者必读(二):史上最全挪动弱网络优化办法总结》
《从客户端的角度来谈谈挪动端 IM 的音讯可靠性和送达机制》
《古代挪动端网络短连贯的优化伎俩总结:申请速度、弱网适应、平安保障》
《挪动端 IM 中大规模群音讯的推送如何保障效率、实时性?》
《挪动端 IM 开发须要面对的技术问题》
《开发 IM 是本人设计协议用字节流好还是字符流好?》
《IM 音讯送达保障机制实现(一):保障在线实时音讯的牢靠投递》
《IM 音讯送达保障机制实现(二):保障离线音讯的牢靠投递》
《如何保障 IM 实时音讯的“时序性”与“一致性”?》
《一个低成本确保 IM 音讯时序的办法探讨》
《IM 单聊和群聊中的在线状态同步应该用“推”还是“拉”?》
《IM 群聊音讯如此简单,如何保障不丢不重?》
《谈谈挪动端 IM 开发中登录申请的优化》
《挪动端 IM 登录时拉取数据如何作到省流量?》
《浅谈挪动端 IM 的多点登录和音讯漫游原理》
《齐全自已开发的 IM 该如何设计“失败重试”机制?》
《通俗易懂:基于集群的挪动端 IM 接入层负载平衡计划分享》
《微信对网络影响的技术试验及剖析(论文全文)》
《开源 IM 工程“蘑菇街 TeamTalk”的现状:一场有始无终的开源秀》
《如约而至:微信自用的挪动端 IM 网络层跨平台组件库 Mars 已正式开源》
《子弹短信光鲜的背地:网易云信首席架构师分享亿级 IM 平台的技术实际》
《微信技术分享:微信的海量 IM 聊天音讯序列号生成实际(算法原理篇)》
《自已开发 IM 有那么难吗?手把手教你自撸一个 Andriod 版繁难 IM (有源码)》
《融云技术分享:解密融云 IM 产品的聊天音讯 ID 生成策略》
《IM 开发基础知识补课(六):数据库用 NoSQL 还是 SQL?读这篇就够了!》
《适宜老手:从零开发一个 IM 服务端(基于 Netty,有残缺源码)》
《拿起键盘就是干:跟我一起徒手开发一套分布式 IM 零碎》
《适宜老手:手把手教你用 Go 疾速搭建高性能、可扩大的 IM 零碎(有源码)》
《IM 里“左近的人”性能实现原理是什么?如何高效率地实现它?》
《IM“扫一扫”性能很好做?看看微信“扫一扫识物”的残缺技术实现》
《IM 音讯 ID 技术专题(一):微信的海量 IM 聊天音讯序列号生成实际(算法原理篇)》
《IM 音讯 ID 技术专题(二):微信的海量 IM 聊天音讯序列号生成实际(容灾计划篇)》
《IM 音讯 ID 技术专题(三):解密融云 IM 产品的聊天音讯 ID 生成策略》
《IM 音讯 ID 技术专题(四):深度解密美团的分布式 ID 生成算法》
《IM 音讯 ID 技术专题(五):开源分布式 ID 生成器 UidGenerator 的技术实现》
《IM 音讯 ID 技术专题(六):深度解密滴滴的高性能 ID 生成器(Tinyid)》
《IM 开发宝典:史上最全,微信各种性能参数和逻辑规定材料汇总》
《IM 开发干货分享:我是如何解决大量离线音讯导致客户端卡顿的》
《零根底 IM 开发入门(一):什么是 IM 零碎?》
《零根底 IM 开发入门(二):什么是 IM 零碎的实时性?》
《零根底 IM 开发入门(三):什么是 IM 零碎的可靠性?》
《零根底 IM 开发入门(四):什么是 IM 零碎的音讯时序一致性?》
《IM 开发干货分享:如何优雅的实现大量离线音讯的牢靠投递》
《IM 开发干货分享:有赞挪动端 IM 的组件化 SDK 架构设计实际》
《一套亿级用户的 IM 架构技术干货(下篇):可靠性、有序性、弱网优化等》
《IM 扫码登录技术专题(一):微信的扫码登录性能技术原理调试剖析》
《IM 扫码登录技术专题(二):市面支流的扫码登录技术原理调试剖析》
《IM 扫码登录技术专题(三):通俗易懂,IM 扫码登录性能具体原理一篇就够》
《了解 IM 音讯“可靠性”和“一致性”问题,以及解决方案探讨》
《阿里技术分享:闲鱼 IM 基于 Flutter 的挪动端跨端革新实际》

更多同类文章 ……

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

▲ 本文在公众号上的链接是:点此进入。同步公布链接是:http://www.52im.net/thread-36…

正文完
 0