QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

Flutter IM 跨端架构设计和实现

  • 2021-06-29
  • 本文字数:3461 字

    阅读完需:约 11 分钟

Flutter IM跨端架构设计和实现

现状

闲鱼 IM 框架构建于 2016-2017 年,期间多次迭代升级导致历史包袱累积多,后经 IM 界面 Flutter 化,造成架构更复杂,开发层面总结闲鱼当前架构主要存在如下几个问题:


• 研发效率较低:当前架构开发需求涉及到 Android/iOS 双端的逻辑代码以及 Flutter 的 UI 界面代码,定位问题往往只能从 Flutter UI 表象追查到 Native 逻辑漏洞;

• 架构层次较差:架构设计上分层不清晰,业务逻辑夹杂在核心的逻辑层致使代码变更风险大;

• 性能测试略差:核心数据源存储 Native 内存,需经 Flutter Plugin 将数据源序列化上抛 Flutter 侧,在大批量数据源情况下性能表现较差;

从舆情层面总结闲鱼 IM 当前架构的主要问题如下:

• 定位问题困难:线上舆情反馈千奇百怪,测试始终无法复现相关场景,因此很多时候只能靠现象猜测本质;

• 疑难杂症较多:架构不稳定性造成出现的问题反复出现,当前疑难杂症主要包括未读红点计数,iPhone5C 低端机器架构,以及多媒体发送等多个问题;

• 问题差异性大:Android 和 iOS 两端逻辑代码差异大,包括现存埋点逻辑都不尽相同,因此排查问题根源时候双端都会有不同问题根因,解决问题方案也不相同;

业界跨端方案

为解决当前 IM 痛点,闲鱼今年特起关于 IM 架构升级项目,重在解决客户端中双端一致性痛点,初步设想方案就是实现跨端统一的 Android/iOS 逻辑架构;在当前行业内跨端方案可初步归类如下图架构,在 GUI 层面的跨端方案有 Weex,ReactNative,H5,Uni-APP 等,其内存模型大多需要通过桥接到 Native 模式存储;在逻辑层面的跨端方案大致有 C/C++等与虚拟机无关语言实现跨端,当然汇编语言也可行;此外有两个独立于上述体系之外的架构就是 Flutter 和 KMM(谷歌基于 Kotlin 实现类似 Flutter 架构),其中 Flutter 运行特定 DartVM,将内存数据挂载其自身的 isolate 中;


null

考虑闲鱼是 Flutter 的前沿探索者,方案上优先使用 Flutter;然而 Flutter 的 isolate 更像一个进程的概念(底层实现非使用进程模式),相比 Android,同一进程场景中,Android 的 Dalvik 虚拟机多个线程运行共享一个内存 Heap,而 DartVM 的 Isolate 运行隔离各自的 Heap,因而 isolate 之间通讯方式比较繁琐(需经过序列化反序列化过程);整个模型如下图所示:


null

若按官方混合架构实现 Flutter 应用,开启多个 FlutterAcitivty/FlutterController,底层会生成多个 Engine,对应会存在多个 isolate,而 isolate 通讯类似于进程通讯(类似 socket 或 AIDL),这里借鉴闲鱼 FlutterBoost 的设计理念,FlutterIM 架构将多个页面的 Engine 共享,则内存模型就天然支持共享读取,原理图如下:


null

Flutter IM 架构设计

新老架构对比

如下图是一个老架构方案,其核心问题主要集中于 Native 逻辑抽象差,其中逻辑层面还设计到多线程并发使得问题倍增,Android/iOS/Flutter 交互繁杂,开发维护成本高,核心层耦合较为严重,无插拔式概念;


null


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


null


架构从上至下依次为业务层分发层逻辑层以及数据源层,数据源层来源于推送或网络请求,其封装于 Native 层,通过 Flutter 插件将消息协议数据上抛到 Flutter 侧的核心逻辑层,处理完成后变成 Flutter DB 的 Enitity 实体,实体中挂载一些消息协议实体;核心逻辑层将繁杂数据扁平化打包挂载到分发层中的会话内存模型数据或消息内存模型数据,最后通过观察者模式的订阅分发到业务逻辑中;Flutter IM 重点集中改造逻辑层和分发层,将 IM 核心逻辑和业务层面数据模型进行封装隔离,核心逻辑层和数据库交互后将数据封装到分发层的 moduleData 中,通过订阅方式分发到业务层数据模型中;此外在 IM 模型中 DB 也是重点依赖的,个人对 DB 数据库管理进行全面封装解,实现一种轻量级,性能佳的 Flutter DB 管理框架;

DB 存储模型

Flutter IM 架构的 DB 存储依赖数据库插件,目前主流插件是 Sqflite,其存储模型如下:


null


依据上图 Sqflite 插件的 DB 存储模型会有 2 个等待队列,一个是 Flutter 层同步执行队列,一个是 Native 层的线程执行队列,其 Android 实现机制是 HandlerThread,因此 Query/Save 读写在会同一线程队列中,导致响应速度慢,容易造成 DB SQL 堆积,此外缺失缓存模型,于是个人定制如下改进方案:


null

Flutter 侧通过表的主键设计查询时候会优先从 Entity Cache 层去获取,若缓存不存在,则通过 Sqflite 插件查询,同时改造 Sqflite 插件成支持 sync/Async 同步异步两种方式操作,对应到 Native 侧也会有同步线程队列和异步线程队列,保证数据吞吐率;但是这里建议查询使用异步,存储使用同步更稳妥,主要怕出现多个相同的数据元 model 同一时间进入异步线程池中,存储先后顺序无法有效的保证;

ORM 数据库方案

IM 架构重度依赖 DB 数据库,而当前业界还没有一个完备的数据库 ORM 管理方案,参考了 Android 的 OrmLite/GreenDao,个人自行设计一套 Flutter ORM 数据库管理方案,其核心思想如下:


null

由于 Flutter 不支持反射,因此无法直接像 Android 的开源数据库方式操作,但可通过 APT 方式,将 Entity 和 Orm Entity 绑定于一身,操作 OrmEntity 即操作 Entity,整个代码风格设计也和 OrmLite 极其相似,参考代码如下:


null

IM 内存数据模型

FlutterIM 架构在内存数据模型主要划分为会话和消息两个颗粒度,会话内存数据模型交托于 SessionModuleData,消息内存数据模型交托于 MessageModuleData;会话内存数据有一个根节点 RootNotice,然后其挂载 PSessionMessageNotice(这里 PSessionMessageNotice 是 ORM 映射的会话 DB 表模型)子节点集合;消息内存数据会有一个 MessageConatiner 容器管理,其内部挂载此会话中的 PMessage(PMessage 是 ORM 映射的消息 DB 表模型)消息集合。


依据上一章节,PSessionMessageNotice 设计了一个 OrmEnitity Cache,考虑到 IM 中会话数是有限的,因此 PSessionMessageNotice 都是直接缓存到 Cache 中,这种做法的好处是各地去拿会话数据元时候都是缓存中同一个对象,容易保证多次重复读写的数据一致性;而 PSessionMessageNotice 考虑到其数量可以无限多的特殊性,因此这里将其挂载到 MessageContainer 的内存管理中,在退出会话的时机会校验容器中 PMessage 集合的数量,适当缩容可以减少内存开销,模型如下图所示:


null

状态管理方案

Flutter IM 状态管理方案比较简单,对数据源 Session/Message 维度使用观察者模式的订阅分发方式实现,架构类似于 EventBus 模式,页面级的状态管理无论使用 fish-redux,scopeModel 或者 provider 几乎影响面不大,核心还是需保留一种插拔式抽象更重要;架构如下图:


null

IM 同步模型方案

如下是当前现状的消息同步模型,模型中存在 ACCS Thread/Main Thread/Region Thread 等多线程并发场景,导致易出现多线程高并发的问题;native 的推送和网络请求同步的隔离方案通过 Lock 的锁机制,并且通过队列降频等方式处理,流程繁琐且易出错。整体通过 Region Version Gap 去判断是否有域空洞,进而执行域同步补充数据。


null

改进的同步模型如下,在 Flutter 侧天然没多线程场景,通过一种标记位的转化同步异步实现类似 Handler 消息队列,架构清晰简约了很多,避免锁带来的开销以及同步问题。


null

进展以及性能对比

• 针对架构层面:在 FlutterIM 架构中,重点将双端逻辑差异性统一成同一份 Dart 代码,完全磨平 Android/iOS 的代码差异性带来的问题,降低开发维护,测试回归,视觉验收的一半成本,极大提高研发效率;架构上进行重构分层,实现一种解耦合,插拔式的 IM 架构;同时 Native 到 Flutter 侧的大量数据上抛序列化过程改造成 Flutter 引用传递,解决极限测试场景下的私聊卡顿问题;

• 针对线上舆情:补齐 UT 和 TLog 的集团日志方式做到可追踪,可排查;另外针对于很多现存的疑难杂症重点集中专项解决,比如 iphone5C 的架构在 Flutter 侧统一规划,未读红点计数等问题也在架构模型升级中修复,此外多媒体音视频发送模块进行改造升级;

• 性能数据对比:当 IM 架构的逻辑层和 UI 层都切换成 Flutter 后,和原先架构模式初步对比,整体内存水位持平,其中私聊场景下小米 9 测试结果内存下降 40M,功耗降低 4mah,CPU 降低 1%;极限测试场景下新架构内存数据相比于旧架构有一个较为明显的改观,主要由于两个界面都使用 Flutter 场景下,页面切换的开销降低很多;

展望

JS 跨端不安全,C++跨端成本有点高,Flutter 会是一个较好选择;彼时闲鱼 FlutterIM 架构升级根本目的从来不是因 Flutter 而 Flutter,是由于历史包袱的繁重,代码层面的维护成本高,新业务的扩展性差,人力配比不协调以及疑难杂症的舆情持续反馈等等因素造成我们不得不去探索新方案。经过闲鱼 IM 超复杂业务场景验证 Flutter 模式的逻辑跨端可行性,闲鱼在 Flutter 路上会一直保持前沿探索,最后能反馈到生态圈;总结一句话,探索过程在于你勇于迈出第一步,后面才会不断惊喜发现


本文转载自:闲鱼技术(ID:XYtech_Alibaba)

原文链接:Flutter IM跨端架构设计和实现

2021-06-29 07:003321

评论 2 条评论

发布
用户头像
有兴趣卖解决方案吗,关于移动端的,我们是华东院的
2021-09-17 13:51
回复
用户头像
xxxx

FlutterAcitivty/FlutterController

2021-07-01 18:18
回复
没有更多了
发现更多内容

难忘阿里,4面技术5面HR附加笔试面,走的真艰难真心酸

Java 编程 程序员 面试 架构师

小树量化机器人系统开发(马丁策略)

薇電13242772558

区块链 数字货币

Fabric架构演变之路

趣链科技

区块链 fabric 联盟链架构 演变

字节跳动的ToB生意,为什么需要火山引擎?

ToB行业头条

【立刻报名】加速开发 Perforce on Tour China 2021-龙智

龙智—DevSecOps解决方案

毕业5年的同学突然告诉我,他已经是年薪50W的Java架构师了

Java架构师迁哥

拼多多电商部java岗三面落选,记下的面试题,不睡觉都要背下来!

Java 程序员 架构 面试

一些有意思的句子

IT蜗壳-Tango

IT蜗壳 6月日更

3D场景搭建的隐秘功能——时间轴

ThingJS数字孪生引擎

大前端 物联网 可视化 3D可视化 数字孪生

【案例】构建应急指挥体系,实现生产过程实时监控

星环科技

一文回顾 Java 入门知识(中)

逆锋起笔

Java 后端 JAVA开发 java基础 javase

一周信创舆情观察(5.24~5.30)

统小信uos

三位一体:打造软硬服一体化的区块链平台

趣链科技

区块链 联盟链 Baas 一体机 底层平台

将DataX执行结果通过钉钉上报

白粥

DataX

贝特瑞新能源汽车的速度与激情

亚马逊云科技 (Amazon Web Services)

奉劝各位准备面试的Java程序员耗子尾汁,赶紧扔掉网上那些千篇一律的面试题

Java架构之路

Java 程序员 架构 面试 编程语言

勒索病毒卷土重来?看亚马逊云科技如何保护你的网络安全!

亚马逊云科技 (Amazon Web Services)

【星环案例】我们用TDH+Sophon把工厂“搬”进高校实验室,推进产学研一体化

星环科技

Polkadot“升级”之道

趣链科技

区块链 区块链技术 polkadot

博云容器云 3.2 发布:核心能力再提升,易用性再升级

BoCloud博云

容器

博睿数据深化信创布局,通过华为鲲鹏920和统信UOS测试认证

博睿数据

信创 国产化 博睿数据

有道精品课全链路测试的改进和思考

有道技术团队

测试 有道精品课

Java“圣经”学累了?那就看看这些通俗易懂的内容吧

Java架构师迁哥

2021年阿里/腾讯/美团/字节1万道Java中高级面试题汇总,新鲜出炉

Java架构师迁哥

联邦学习这件小事

趣链科技

区块链 联邦学习 技术架构

VRIO模型 - 发现自己的核心资源与能力

石云升

创业 职场经验 管理经验 6月日更

我们并不需要 Deno

LeanCloud

node.js deno 开发工具 JavaScrip

农业SaaS,「无人关注」的万亿市场

ToB行业头条

迎战大厂!“金九银十”和秋招通过率达95%的Java面试要点集锦

Java 程序员 架构 面试

大专学历成功拿下阿里offer,分享面经及我的Java面试复习资料

Java架构之路

Java 程序员 架构 面试 编程语言

dubbo使用curator作为zk客户端优雅停机存在的问题

林一

zookeeper dubbo curator

Flutter IM跨端架构设计和实现_大前端_闲鱼技术_InfoQ精选文章