支付宝在移动端如何实现轻耦合、弹性动态的开发模式
发表时间:2023-10-08 06:02:32
文章来源:炫佑科技
浏览次数:158
菏泽炫佑科技
支付宝在移动端如何实现轻耦合、弹性动态的开发模式
今天,我将与大家分享支付宝如何在移动端实现轻耦合、灵活动态的开发模式,并对其技术选型和实践经验进行深入剖析。 演讲嘉宾是来自蚂蚁金服mPaaS客户端核心开发的文胜章。 以下为演讲全文:
我们提供了一个名为mPaaS的移动开发平台,现已在阿里巴巴正式发布。 它首先是一个源自我们支付宝的移动组件,目的是打造一个快速迭代的架构和动态的能力。 它是一整套完整的解决方案,包括移动终端开发SDK、移动终端构建工具以及一整套后端服务和工具作为一个整体系统产品。 我们要做的主要是利用移动开发平台mPaaS来创建性能更好的APP。 今天我们直播分享的是支付宝使用mPaaS的一些动态实践。
灵活动态的端到端架构分析
这里我们要介绍的**点是弹性动态端的能力。 首先我们支付宝面临的一些问题是海量的业务,然后还有一些传统的解决方案。 这是一个老生常谈的话题。 那么第二个就是一个高可用、及时快速发布的监控和运维系统,它包括本地条件、灰度等能力,然后是快速回滚、快速迭代的能力。 那么第三点就是开放我们的一些解决方案。
Part1:利用架构应对海量业务需求
**部分介绍如何用一个价格应对海量的业务需求。 我们知道支付宝是一个国家级的APP,承载着很多的业务。 如果我们采用传统的迭代方式,肯定无法满足我们当前业务的需求。 比如我可能需要一个双11活动、双十二活动或者其他一些运营活动,我们需要一些非常快的迭代能力,不仅是IOS和端,还需要一些快速回滚的能力。 目前我们在移动端有四个这样的能力。 以下是 4 个功能的示例。 一个是,然后是Html5,这是*新的跨端解决方案app开发,目前也在我们尝试的范围之内。
我们可以看一下这四种能力,它们的比较如下。 对于我们开发的同学来说,我们的开发成本是*低的。 因为我们是开发出身的,所以我们基本上不需要学习什么特别的东西,所以我们有一整套的UI架构体系和UI API调用。 类非常熟悉,用户体验度也较低。 我们基于iOS UIKit以及一整套UI架构。 如果我们使用原生解决方案,它的体验将与当前的移动硬件能力相同。 很好,但是他的动力却变得很弱。
我们没有办法去交付新的能力,包括写一个营销组件,这个方法也是不可能的。 由此看来,我们早期在寻找移动终端的时候,为了解决重大问题,首先想到的就是Html5解决方案。 他的话就是基于这样一个技术栈,然后把前端页面写进去。 同时为了和这边交互,我们介入了一些当时被谈论很多的叫做IOS和规则的组件。 基于这两套解决方案,我们可以对接它们之间的能力。 连接之后,我们可以获得一些简单的交互和复杂的操作能力。
比如说这个时候我们需要动态下发一个操作页面,那么我们就可以用Html写一个Html网页支付宝在移动端如何实现轻耦合、弹性动态的开发模式,然后发布到我们的平台上,然后这个时候再下发到*后,快速的渲染一些东西喜欢这个页面。 随着Html5技术的发展,我们开始思考是否可以使用Html这样的DSL来编写我们想要的内容。 在那个阶段,我们有像 React-JS 和 React- 这样的解决方案。
然后React——是一个使用React的DSL,然后渲染组件的解决方案。 对于我们来说,首先我们需要学习一些前端开发的语言,但是因为它可以使用前端开发的语言,所以它绕过并提供了一些动态的能力,所以它的实际体验是这样的是一样顺利。 但在这个问题上,因为要兼容两端的特性,所以在过程中造成了很多问题。 所以我们投入了很大的精力去解决这个问题,但是解决的同时却不是一件容易的事情。 但它的动态性是我们非常看重的,因为首先它在其前端和模型的基础上简化为Flex模型。 然后原有的一些系统管理工具就被废弃了。 所以现阶段我们已经将RN扩展到很多解决方案。 淘宝也有像Weex这样的解决方案,*近又发布了这个解决方案,实际上完全颠覆了原来的开发模式。 事实上,它对我们来说从头到脚都是新的。
和上面IOS上的一样,也是基于一个解决方案。 它在上面进行绘制,然后同时接管一些事件,然后在自己的单一引擎上执行一些渲染。 用于响应某些用户交互请求的操作和响应。 对我来说,首先我们要学习它的dart语言,这是**个成本。 学习了Dart语言之后,我们仍然需要了解它整个引擎的工作流程。 这是第二个成本。 此后,其对动态的支持目前处于官方层面放弃的状态。 它并不是想说它有动态交付的能力。 它基于skia引擎解决方案。 Skia是一款性能不错的渲染引擎,因此它的用户体验也非常好。 这就是我们四种能力之间的差异。 下面是四种能力的比较。 我们看一下基于H5的解决方案,它提供了容器和离线包的架构。
传统的H5页面,我们只是连接一个到客户端本身,然后提供几个JS API。 将来我们希望当我们的HTML页面下载到我们本地时,能够与服务器进行通信。 您还可以获得一些本地能力。 但我们知道它的渲染性能以及首屏白屏之类的问题还没有解决,所以为了解决这些问题,让它的体验更接近体验,我们提供了它目前的这种架构。 我们这里使用的,首先首先要解决的**个问题就是在手机上使用UC内核,因为对于我们来说,uc内核可以为各种外部版本、不同机型铺平道路。 存在一些不可避免的差异。 这是我们在前端领域遇到的*常见的浏览器兼容性问题。
在解决这个问题的基础上,我们希望赋予容器更多的能力。 首先要统一容器的JS性能。 这是中间层的平面图,第三个绿色层。 我们铺好这一层之后,对于前端来说,他只有他的业务细节和具体的业务流程。 我们的容器包含离线包的拉取。 对于我们来说,离线包是解决首屏渲染问题的*大起点。 当我们把离线包的全部能力集成到一个容器中时,我们使用了像MDS这样的发布平台,我们这里称之为MDS。
通过发布平台,我们可以快速的将我们的离线包发布到用户的手机上。 那么当用户打开我们的页面时,就不需要花费太多的时间来快速打开我们的页面。 那么离线包的发布和离线包的更新都在我们的掌控之中。 同时我们可以根据一些算法快速预测用户是否需要快速开启这个服务。 如果需要开通这样的服务,可以提前发送到用户的手机上,然后用户在开通服务时就可以快速使用。 离线包。
然后在容器下面的各层中,我们做了一层和原有能力连接的层,就是封装相同的API接口,比如网络、多媒体、Push等。 那么容器本身就可以快速升级。 在分发过程中,我们可以将*新的优势内核分发到用户的手机上,用户可以无意识地升级自己的uc内核,体验*新的功能。 因此,除此之外,我们将每个业务称为应用程序。
所以我们这里有ABCD。 比如说我们有N个业务,那么每一个应用在我们身上都是一个业务层面的概念。 那么生意就相当孤立了。 在隔离的情况下,我们可以对配电盘有一个很好的控制,还有一层控制,这样我们就可以更好的控制故障的发生。 整个H5应用的启动流程大致分为几层。 首先,它的入口部分可以使用URL或一些按钮来启动。 所以对于我们的每一个H5应用,我们都抽象成一层概念,叫做APP。
在入口处,我们可以传入一些我们启动的参数,然后将它们传递给我们调用的H5容器。 然后启动应用程序后,我们会有一些回调,比如框架的生命周期。 对于我们来说,有诸如,之类的生命周期回调。 所以在这一层中,在 和 之间会调用图像一侧的图像,然后调用完成后会创建一个页面。 这个页面就是我们H5容器的页面,然后里面会有一些像脚本的加载,像我们内置写的一些插件的加载,比如说你想对一些请求做一层监控,一些业务指标,在这里写一个插件是一个非常好的选择。
我们对外部容器更多的做的就是希望我们和外界之间有一个顺畅的沟通渠道。 这里,我们在PPT中演示的是一个JS概念。 我们将使用该方法将 JS 代码传输到外部端,并将一些消息发送回 Web 端。 我们希望实现极致的网络体验。 Web体验无非就是几个概念,首先是首页的加载问题,然后是不同平台之间的差异问题。 *后,还有一些离线资源的缓存问题。 除了这些问题之外,我们还提供了很多解决方案。
首先**点就是我们把网络请求从本层细化到我们这一层,因为我们对于网络有更好的能力,比如我们可以使用除了HTTP之类之外的协议,如果我们构建一些其他协议,我们也会解决一些交叉问题。 因为APP是在我们的控制之下,所以我们也可以对访问的域名做一些控制。 那么在此基础上我们就可以解决前后端分离的问题了。 页面资源可以提前加载,所以对于前端来说,前端只关心其业务数据的通信。
对于第二点,我们提供了差分更新的能力。 差异更新的概念是什么? 比如这次我去投递一个1MB的离线包,然后我发现离线包有一些bug,所以我就对其进行了修复。 比如我发布了1.0.1版本,那么这两个离线包的改动可能很小,比如只有一个字符串的改动或者几行代码的改动。 这时候你可以使用差异更新的方式,只将变化的部分提交到我们的MDS发布平台,那么MDS就会在合适的时候进行更新。 将这部分差异数据发送到我们端,然后端可以根据差异自动合并一个新的离线包。
那么,当用户下次打开时,你的离线包就已经更新了。 这个过程不仅可以使流量占用非常小,而且可以快速响应业务端的需求。
我们讲的第三点是推拉组合的概念,这个概念其实还是蛮有趣的。 因为我们是传统的HT模式,所以我们总是有一个拉动的概念。 我在客户端提到这一点,然后服务器返回它。 当然http2是有一个概念的,所以我们并不是说我们在上面做了一个加强,我们有一个组件,叫做sync。 对于mPaaS平台来说,是稳定的长连接。 然后服务器可以通过长链接提前向客户端发送一些想要的东西,比如提前发送离线包的概念,或者一些其他的数据,特别是一些基于事件的数据。
那么第四点就是如果我们的离线包发布失败的话,我们可以设置一个在线流程。 这个过程是为了防止我们的离线包下载失败。 这样做是为了确保正确性。 然后就是我讲的独立浏览器内核的问题。 也许我们之前遇到过更多的情况。 现在我们支持的版本仍然是4.3、4.4及以上。 仍然会存在一些问题。 所以我们的离线包,我们的UC是实时动态更新的,不遵循系统。 因此,我们尽早发布的更新可以帮助用户更好地稳定离线包体验,减少前端Bug的发生。
后面的部分我们会讲一些深度定制的组件。 在这方面,我们提供了一些解决方案,比如Ant,可以让用户快速介入构建页面。 所以*后一点就是监控。 其实监控是这里*无聊的部分,但却是*重要的部分。 因为我们需要对业务的稳定性和我们自己的业务点做一些监控,那么这些监控完成之后我们就可以快速的响应用户的需求,解决用户遇到的一些问题。 同时,我们可以收集一些运营数据。 ,然后为接下来的产品改进和bug修复提供非常有效的帮助。
我们的H5容器包含非常巨大的可扩展性。 我们首先提供一些JS API,可以让H5代码具备前面提到的调用能力。 它不仅仅是一些普通的能力,还包括数据存储、全局广播、以及定制的扩展API。 然后我们在容器上提供一些容器插件。 至于容器插件,它根据事件进行响应。 我们在H5中的容器上提供了一系列的生命周期,因此当生命周期回调响应时,我们可以在插件中接收到这个生命周期事件。
那么我们就可以根据这个事件来做各种功能,然后切换这个功能其实就是*能满足需求的功能了。 然后我们可以根据特定的情况做一些开关配置,比如根据人群、机器型号、地区等来做这些开发配置,然后我们就可以针对特定的地区、特定的人群进行提前灰度。 ,或者AB的能力。 我们的 H5 容器*重要的特点之一是它比原生容器稳定得多。 我们这里有两个指标,一个是PV的崩溃率,一个是PV的ANR概率。 那么崩溃率就是。 那么我们这里是传统容器的两倍多,所以ANR的概念就是你在划桨过程中卡住的概率,我们这里解决的两个主要核心问题是稳定性和体验不一致。
第二部分:监控+发布平台,满足业务稳定运行和快速迭代
然后我们来说说我们的监控和发布平台,因为这是围绕我们H5容器的生态,需要非常大的后端能力。 首先我们需要具备快速发布的能力,因为我们知道基于原生的H5页面其实是具备实时发布能力的。 实时发布的概念是,如果你拥有一台服务器,那么你就可以发布自己的内容,当前端页面打开时,它是实时更新的。 如果使用离线包的话,他确实会失去一些快速释放的能力,但是我们这里需要补偿他快速释放的能力。
所以当我们**次访问我们的MDS时,我们的离线包首先发布在MDS上。 然后MDS会根据你之前配置的一系列东西,然后根据我们之前客户端上的一些条件,比如你是否开启了灰度开关,或者是整个网络,将我们的离线包发布到CDN上。 如果灰度开关打开了,你需要根据你的一些灰度配置,然后通过客户端和服务端进行调整。 客户端和MDS之间有一些请求,然后我们的离线包的地址被发送到客户端。 然后客户端就会得到这个地址,从CPN下载我们的离线包。 这就是我们提供的。 具有快速释放能力。 那么快速发布不仅需要具备智能灰度的能力,还需要具备增量拆分离线包的能力。 这种能力对于客户来说是看不见的。 因为客户只需上传两个版本的离线包到我们的服务器,我们的服务器会自动计算两个版本的离线包之间的差异,然后将差异发送给客户端。 我们还需要确保我们的 MDS 性能需要满足非常高的要求。 那么我们MDS的性能QPS可以达到每秒5万,到达终点的到达率可以达到99.99%。
那么接下来要讲的就是监控和诊断,所以监控其实是我们非常需要关注的一个维度,因为当我们完成业务开发交付给用户的时候,如果用户体验非常不好,那么我们的保留率很低。 所以我们需要在崩溃、流畅度、电量、流量等,以及一些服务不可用的问题上做出一些努力。 我们去埋点之后,当我们收集用户的使用情况时,我们需要上报。 所以如果实现了实时报告,这个报告策略其实是不合理的。
因为首先会影响用户体验,因为如果我们实时上报的话,我们可能一直有一个进程打开,或者可能有一个线程要上报。 其次,也会对用户流量产生巨大的影响。 那么同时我们也需要考虑用户在使用我们的APP时的情况,比如做一些定制化的开关,或者做一些特殊的采样。 例如,如果用户向我们报告使用APP时发生的崩溃情况,那么我们不需要收集整个网络的崩溃情况,因为用户本身的使用场景可能比较特殊,所以我们需要有具体的用户有固定的抓取能力。
然后我们有三种报告方法。 **种是自动上传,第二种是定期检查上传,比如每小时或每隔一天检查一次。 第三点是诊断命令驱动的上传。 这就是我刚才提到的场景。 如果用户报告崩溃,那么我们需要用户报告他的电子邮件地址,或者帐户名等,然后我们才能准确地捕获用户手机上的日志。 然后根据用户上传的一些日志,我们可以分析出页面的一个跳转路径,然后对APP本身产生的一些日志进行一些分析。 分析完之后我们就可以做出一些决定,比如如何优化这些东西,那么如果我们的Crash和ANR率达到一定程度,我们就需要采取一些措施来断路,比如禁用或者禁用离线包页面,然后要么修复要么修复它这三个过程。
这是我们提供的四种能力。 首先**点是故障隔离,也就是说如果我们发现这个页面出现故障,我们需要提前打开某个开关。 如果是新的业务,比如开关打开了,我们需要立即将其关闭,屏蔽之后再进行一个止血的过程。
那么第二点就是如果我们的闪屏页面出现了,因为这个时候用户可能无法进入我们的APP,所以我们需要进入安全模式。 这时候我们就需要在安全模式下对一些数据进行一些诊断上传。 然后清除我们APP中的一些数据并重新打开它。 这是一种自动恢复能力。
第三点是我们需要进行一些流量熔断。 比如说,如果我们的网络调用达到了一定的请求或者达到了一定的程度,那么有很大的概率,比如我们的服务器或者客户端的APP业务端会收到DDOS的A场景,那么这个时候我们就需要成为交通的导火索。
第四点是我们一个非常重要的动态能力的修复。 嗯,它包含几个内容。 **点就是前面提到的开关。 第二点是离线包的版本更新。 例如,如果之前的离线包出现了一些问题,我们需要及时修复,上传,然后快速发布到全网。 那么第三点是基于原生代码的。 对于,我们仍然使用该解决方案,可以修复Java代码,然后它可以在我们的mPaaS后台同时进行监控和回滚。 点击一个回滚按钮,然后我们就快速回滚这些新发布的东西,因为谁也不能保证自己下次写的代码就没有bug。
所以只要我们验证没有问题,那么我们的修复就可以发布。 如果热修复出现问题,那么我就必须快速恢复并发布新补丁。 所以对于我们来说,我们的发布可能会比较慢,但是如果我们采用H5的解决方案,我们的H5发布肯定会比H5发布更快。 假设我们一个APP中有N个产品,它们之间的开发节奏是这样的。 那么他们整个产品的生命周期就是左边的一个环形结构。 事实上,这仍然是一种相当传统的沟通方式。 首先业务方制定目标,然后开发方构建代码。 然后我们进行灰度连续监测。 正式发布后,我们将进行运维监控。 运维监控结束后,我们会再做一次灰度验证,然后设定新的目标。
对于不同的版本,这里重点关注的是灰度的概念。 对于灰度,我们需要了解用户这边的一些条件。 比如这个时候我们需要做一个基于手机的性能优化方案,那么我们就需要使用条件来过滤掉我们的内容。 比如CPU是骁龙600系列或者500系列的低端CPU,那么就验证一下我们这次的性能修复包的性能。
Part3:更好的解决方案,HTML5与小程序的差异化分析
我们需要谈谈*近非常流行的小程序解决方案。 小程序是基于H5开发方案的升级架构。
首先,小程序是一种基于Web技术的新型移动应用格式,然后集成了原生能力。 所以对于小程序来说,和H5*大的区别就是H5本身其实是一个开放的技术,但是小程序就相当于一个完整的开发框架。 然后你继续按照开发框架和DSL编写相应的业务代码,然后编译成一个小程序包,然后发送到相应的平台。 该平台可以根据您的一组 DSL 渲染其页面之一。 当然,它的渲染引擎是可以随时更换的,而且不一定是*新的渲染引擎。 比如可以基于skia渲染来编写。 那么小程序有四个优点。 一是获取方便。 例如,您可以通过扫描二维码直接打开。 它不需要您设置服务器或考虑 CDN 之类的东西。 二是小程序与小程序之间的链接能力。 然后还有一些小程序和小程序之间的连接能力。 第三,小程序的安全可靠有各大平台保障。 第四点是小程序的渲染。 它由您指定的标签决定。 比如我可以使用原生组件在小程序上渲染一些DSL组件。 在这种情况下,它的渲染能力实际上会比H5有更高的渲染能力。 那么整个小程序的架构如图所示。 小程序的渲染层和逻辑层完全分离。
你可以认为渲染层有选择,所以渲染就是它了。 其实它的一些事件执行,比如一些逻辑的执行,是另外开启一个JS引擎来做这件事的。 然后他们通过层中的一层JS进行通信。 然后逻辑层每次向该层建立一些需要改变的配置信息时,该层就获取渲染层已经渲染好的DOM信息,然后计算差分逻辑。 *后,它被发送到我们的渲染层。 那么每次更新UI的时候,都会渲染一些差异化的数据。 这样的话,我们的渲染层和逻辑层之间的执行是完全隔离的。 这就是我们所说的小程序双线程的一个概念。 同时,由于小程序受到平台容器的保护,我们可以在这里快速开放一些存储网络多媒体能力。 这样的话,我们在使用小程序进行开发时,就可以用*少的成本开发出性能*好、动态能力*强的框架。
同时我们的小程序提供了构建和发布ID的能力。 对于ID的构建,我们现在有一个提供支付宝小程序的IDE。 同时开发支付宝小程序、淘宝小程序、mPaaS小程序。 它们三个虽然技术架构不同,但是它们之间的DSL是一样的,可以使用同一套代码来开发。 所以对于这一层,首先对你传递的参数做一层分析。 分析完成后,提前加载小程序的资源,然后创建渲染页面。 比如我这里提到的,目前是基于UC的。 但不需要基于UC,这对业务来说是完全感觉不到的。 渲染层初始化之后,我们这里会创建一个JS,所以这就是我们刚才讲的逻辑层的一个概念。 。 创建后,会监听原小程序中执行的小程序的JS代码中执行的一些事件,并返回小程序中的一些事件。 然后在小程序的JS引擎中,针对业务代码层面,这些做出一些响应,比如Set Data之类的回调。 调整完成后,会传递到这一层。 该层会将一些原本改变的数据传递给渲染层。 然后渲染层会在下一个事件循环中对这次传递的数据进行差分渲染,然后做完之后我们就可以看到我们想要的产品了,所以这就是我们刚才讲的小程序的双线程概念关于。 逻辑在这里,然后渲染层在这里。
小程序的特点非常标准化,提供了多种能力。 首先,**封装体的结构符合标准要求。 我们必须提供这样的包体结构,然后UI组件和API是分开的。 有了一个能力,我们就可以在入口标准化的情况下,快速的把我们的小程序的内容以及我们的小程序的整体页面控制到一个比较小的开口,这样就可以*大程度的防范各种风险。
同时它的安全性和隐私性控制就在于我们的容器已经被打包了。 比如,当一个小程序想要获取一些隐私相关的权限时,它需要我们这边在UI层面做出一些响应,比如我们想要获得用户位置的能力,或者获得用户的手机号码,我们需要向该级别用户申请权限。 那么同时我们也提供了一些,可以认为是插件,或者类似UI组件的东西。
那么对于我们整个小程序生态来说,目前支付宝的mPaaS小程序在各个地方都有使用,比如饿了么、高德地图、淘票票等等。
在这种情况下,我们把我们整个小程序的能力封装起来,通过mPaaS分发给各个用户。 那么用户集成了我们的mPaaS容器之后,也可以基于这个生态开发自己想要的小程序,然后运行在自己的APP上。 我们希望我们正常、开放的生态环境能够让用户从小程序中受益。 那么你也可以拥有属于自己的动态能力。 我们希望增加用户粘性,进而连接到大量的服务。 如果我们提供服务,我们希望能够快速到达很多终端。
那么我们的mPaaS就是集成到支付宝里面的一套完整的引擎,所以我们的mPaaS提供了从服务端到客户端的几个完整的解决方案。 对于客户端,有客户端SDK和客户端框架。 Then, the the and the is our RPC , the of push and pull. If it is , the Sync just , and if it is , some of my HTPR , then the of mPaaS There is also a , and then some data of users are , and then there are push, and then , and and so on.
The back-end mPaaS has some and , and multi- and , which are some of our own . And , our mPaaS is now based on Cloud.
At , mPaaS has been put on the and to Cloud. is to try it.