作者:初来乍到1231 | 来源:互联网 | 2023-05-19 09:24
本文总结了阿里闲鱼技术团队应用Flutter在对闲鱼IM进行挪动端跨端革新过程中的技术实际等,文中比照了传统Native与当初大热的Flutter跨端计划在一些次要技术实现上的差别,以及针对Flutter技术特点的具体技术实现,值得同样筹备应用Flutter开发IM的技术同行们借鉴和参考。
本文由阿里闲鱼技术团队祈晴分享,本次有订正和改变,感激作者的技术分享。
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…