當前位置:首頁 > 新聞 > 如何快速開(kāi)發(fā)一款APP?
如何快速開(kāi)發(fā)一款APP?
近日,螞蟻金服開(kāi)展了“共戰‘疫情’,技術破局”數字課堂線上直播,我們將(jiāng)系列演講整理并發(fā)布在 “螞蟻金服科技” 公衆号上。
今天,將(jiāng)爲大家分享圍繞支付寶在移動端如何實現輕耦合、彈性動态的開(kāi)發(fā)模式,深度解析其技術選型及實戰經(jīng)驗。演講嘉賓是來自螞蟻金服mPaaS客戶端核心開(kāi)發(fā)的溫盛章,以下爲演講整理全文:
我們提供了一個移動開(kāi)發(fā)平台叫(jiào)做mPaaS,現在在阿裡(lǐ)上面(miàn)已經(jīng)正式的發(fā)布了。他首先是源自于我們支付寶的一個移動端的組件,目的是爲了打造快速叠代的架構和動态化的能(néng)力。它是一整套的方案,包括了移動端的開(kāi)發(fā)SDK,然後(hòu)移動端的構建工具和後(hòu)端的一整套的服務和工具作爲一個整體體系的産品。我們主要要做的事(shì)情是使用移動開(kāi)發(fā)平台mPaaS來打造一個性能(néng)更優的APP。今天我們在這(zhè)邊直播分享的内容是,支付寶使用mPaaS的過(guò)程中的一些動态化的實踐。
彈性動态的端上架構解析
我們在這(zhè)邊,首先要介紹的一個點是彈性動态端的能(néng)力。首先我們在支付寶中面(miàn)臨的一些問題是有海量的業務,然後(hòu)傳統方面(miàn)上的一些Hybrid方案,這(zhè)是一個老生常談的話題了。然後(hòu)第二個是高可用和及時(shí)快速發(fā)布的監控運維體系,這(zhè)裡(lǐ)面(miàn)包含了像局部條件、灰度的能(néng)力,然後(hòu)快速回滾的能(néng)力和快速叠代的一些能(néng)力。然後(hòu)第三點就(jiù)是開(kāi)放出來我們的Hybrid的一些解決方案。
Part1:利用 Hybrid 架構應對(duì)海量業務需求
第一部分我們介紹一下如何使用一個Hybrid的價格去應對(duì)海量的業務需求。我們知道(dào)支付寶它是一個國(guó)民級的APP,它裡(lǐ)面(miàn)承載了非常多的業務,如果使用傳統的叠代方式,肯定滿足不了我們現在這(zhè)些業務的需求,比如說(shuō)我可能(néng)需要一個雙11的活動,雙十二的活動或者是一些别的運營活動的時(shí)候,我們需要非常快速的一些叠代的能(néng)力,不僅在IOS端和安卓端都(dōu)需要有,而且也需要進(jìn)行一些快速回滾。我們目前的話,在移動的端上有4種(zhǒng)這(zhè)樣的能(néng)力。這(zhè)裡(lǐ)是舉個例子的4種(zhǒng)能(néng)力,一種(zhǒng)是Native,然後(hòu)是Html5,ReactNative,Flutter是最新的一個跨端的解決方案,目前也是在我們嘗試的範圍之内。
我們可以看一下這(zhè)4個能(néng)力,它的對(duì)比的情況是這(zhè)樣的。對(duì)于Native的開(kāi)發(fā)同學(xué)來說(shuō),Native的開(kāi)發(fā)成(chéng)本是最低的,因爲我們出身于Native開(kāi)發(fā),所以基本上不需要去學(xué)習一些什麼(me)特殊的東西,所以我們對(duì)整套的一個UI架構的體系和UI的API的調用之類的都(dōu)是非常的熟悉,然後(hòu)它的用戶體驗也是低的,我們基于像iOS UIKit以及 Android一整套的UI架構,如果是使用原生方案的話,它的體驗在目前的移動端的硬件能(néng)力上體驗都(dōu)是非常好(hǎo)的,但是他的動态性就(jiù)變得非常的弱了。
我們沒(méi)有辦法去下發(fā)新的Native一些能(néng)力,包括甚至去寫一個營銷組件,這(zhè)樣的方式也是做不到的。由此我們再找移動端早期的時(shí)候,爲了引用重大問題,我們第一想到的就(jiù)是Html5的方案。他的話是基于WebView的這(zhè)麼(me)一個技術棧,然後(hòu)把前端的頁面(miàn)寫進(jìn)來。同時(shí)爲了和Native這(zhè)邊進(jìn)行交互,我們介入了當時(shí)講了非常多的一個叫(jiào)JsBridge的一些組件,IOS的JsBridge和安卓的JsBridge規律。基于兩(liǎng)套的JsBridge的方案,我們可以跟Native之間的能(néng)力進(jìn)行打通,打通之後(hòu)我們能(néng)獲得一些簡單的交互上的簡單的交互和複雜的運營的能(néng)力。
比如說(shuō)這(zhè)個時(shí)候我們需要動态的下發(fā)一個運營頁面(miàn),那麼(me)我們可以使用Html的寫一個Html的網頁,然後(hòu)把它發(fā)布到我們的平台上,然後(hòu)這(zhè)時(shí)候下發(fā)到Native端,快速的去渲染出這(zhè)樣的頁面(miàn)。在随著(zhe) Html5技術的發(fā)展,我們開(kāi)始去思考能(néng)否使用Html這(zhè)種(zhǒng)DSL去寫,Html去寫一些我們想要的東西。在當時(shí)那個階段的話,我們就(jiù)産生了像React-JS、React-Native這(zhè)種(zhǒng)這(zhè)種(zhǒng)方案。
然後(hòu)React-Native是使用React的DSL然後(hòu)去渲染出Native的組建的這(zhè)麼(me)方案。對(duì)于我們來說(shuō),首先是需要對(duì)于Native來說(shuō)是需要學(xué)習前端開(kāi)發(fā)的一些語言,但是他因爲能(néng)使用前端開(kāi)發(fā)的語言,繞過(guò)WebView同時(shí)又提供了一些動态化的能(néng)力,所以它的實際體驗起(qǐ)來是像是與Native一樣流暢。但是在這(zhè)個問題上,又因爲他爲了兼容兩(liǎng)端的特性,所以導緻了他在處理的過(guò)程中有發(fā)生了非常多的問題,那麼(me)我們在這(zhè)種(zhǒng)問題的解決方案上投入非常多的精力,但是解決起(qǐ)來同時(shí)也不是非常的順手。但是他的動态性卻是我們非常看重的一個東西,因爲首先它基于它的前端的和模型精簡成(chéng)了一個就(jiù)flex這(zhè)麼(me)一種(zhǒng)模型。然後(hòu)抛棄了原先的一些layout的一些系統的layout的管理工具。所以在這(zhè)種(zhǒng)階段上,RN是我們延伸出了非常多方案,淘寶這(zhè)邊也有像Weex這(zhè)樣的一個方案,然後(hòu)最近Google發(fā)布了Flutter這(zhè)個方案,其實算是徹底颠覆了原先的Native的開(kāi)發(fā)模式。其實它對(duì)于我們來說(shuō),全從頭到腳都(dōu)是新的。
像在Android上在IOS上都(dōu)是基于canvas的一個從Native的角度去看,它是基于canvas的方案,他在canvas上進(jìn)行繪制,然後(hòu)同時(shí)去接管canvas的一些事(shì)件,然後(hòu)在他自己的一個單引擎上去進(jìn)行執行一些渲染的動作和響應,響應用戶交互的一些請求。對(duì)Flutter來說(shuō)的話,首先我們要去學(xué)習它的dart語言,這(zhè)是第一個成(chéng)本。dart語言學(xué)完之後(hòu),我們還(hái)要去了解它整個Flutter引擎的工作流,這(zhè)是第二個成(chéng)本。之後(hòu),它對(duì)于動态性的支持,從官方正式的層面(miàn)來說(shuō),目前是處于一種(zhǒng)放棄的狀态。它并不打算說(shuō)有動态下發(fā)的一種(zhǒng)能(néng)力,它基于skia引擎的方案,skia因爲是一個性能(néng)良好(hǎo)的渲染引擎,所以它的用戶體驗也是非常不錯。這(zhè)是我們這(zhè)4種(zhǒng)能(néng)力的一個差别,這(zhè)裡(lǐ)是4個能(néng)力的對(duì)比。我們看一下,基于H5的一個方案的話,提供了這(zhè)麼(me)一個容器加離線包的一個架構。
在傳統的H5頁面(miàn)裡(lǐ)面(miàn),我們隻是一個在客戶端本身接了一個WebView,然後(hòu)提供了幾個JS的API,往後(hòu)希望我們的html頁面(miàn)再下載到我們本地的時(shí)候,既能(néng)跟服務端進(jìn)行通信,又能(néng)獲得一些本地的能(néng)力。但是我們知道(dào)它的渲染性能(néng),還(hái)有像首屏的白屏那種(zhǒng)問題都(dōu)是沒(méi)有解決的,所以說(shuō)我們爲了解決這(zhè)些問題,使得它的體驗更加靠近native體驗的時(shí)候,我們就(jiù)提供了其當前的這(zhè)種(zhǒng)架構。我們在這(zhè)邊使用,首先第1個解決的問題是在Android上使用UC内核的這(zhè)麼(me)一個方案,因爲uc内核對(duì)于我們來說(shuō),他能(néng)去鋪平各個不同Android的版本,各種(zhǒng)不同機型上的外部必有的差異的一些問題,這(zhè)是我們前端領域中最容易碰到的一個浏覽器的兼容問題。
我們在解決這(zhè)個問題的基礎之上,希望賦予容器更多的能(néng)力,我們首先要去統一掉容器的JS bridge的性能(néng)。這(zhè)是當中這(zhè)一層,第3層綠色的這(zhè)一層的方案。我們在這(zhè)一層去鋪平之後(hòu),那麼(me)對(duì)于前端來說(shuō),他隻剩下他的業務細節和具體的業務流程。我們的容器有包含了一個離線包的拉取,離線包對(duì)于我們來說(shuō)是一個解決首屏渲染問題最大的一個抓手。我們使用把離線包的整個能(néng)力去集合在容器裡(lǐ)面(miàn)的時(shí)候,搭配我們的像MDS的一個我們這(zhè)邊叫(jiào)做MDS的一個發(fā)布平台。
搭配發(fā)布平台的話,我們就(jiù)能(néng)很快的發(fā)布我們的離線包到用戶的手機上,那麼(me)在用戶去打開(kāi)我們頁面(miàn)的時(shí)候,并不需要過(guò)多的時(shí)間就(jiù)可以快速的打開(kāi)我們的頁面(miàn)。那麼(me)離線包的發(fā)布和離線包的更新都(dōu)在我們的管控之下。同時(shí)我們可以基于一些算法,快速的先去預測用戶是否需要快速的打開(kāi)這(zhè)項業務,如果需要打開(kāi)這(zhè)樣業務,可以提前傳到用戶的手機上,然後(hòu)用戶在打開(kāi)業務的時(shí)候,就(jiù)能(néng)快速的使用離線包了。
然後(hòu)在容器以下的這(zhè)幾層的話,我們跟原先的Native的能(néng)力做了一層打通,就(jiù)是封裝了相同的一些API接口,比如像網絡、多媒體,Push。然後(hòu)容器本身是可以快速升級的。我們在下發(fā)的過(guò)程中,可以把最新的優勢内核給分發(fā)到用戶的手機上,用戶可以無感知的升級它的uc内核,去體驗最新的一些功能(néng)。那麼(me)在這(zhè)之上,我們把每一個的業務叫(jiào)做一個應用。
那麼(me)我們這(zhè)裡(lǐ)面(miàn)有ABCD比如說(shuō)到N個業務,那麼(me)每一個應用都(dōu)是在我們這(zhè)都(dōu)是一個業務級的概念。那麼(me)業務和業務之間是挺隔離的,在隔離的情況下,我們就(jiù)可以很好(hǎo)的對(duì)發(fā)闆和rollback做一層控制,這(zhè)樣子就(jiù)能(néng)更好(hǎo)的控制故障的發(fā)生。整個H5的應用的啓動流程的話,我們大概有分爲這(zhè)麼(me)好(hǎo)幾層。首先的話,他的入口部分可以使用URL,或者說(shuō)Native的一些按鈕去啓動。那麼(me)對(duì)于我們每個H5的應用來說(shuō),我們都(dōu)給他都(dōu)給它抽象成(chéng)一層叫(jiào)做APP的概念。
在入口的地方,我們可以傳入一些我們啓動的參數,然後(hòu)傳給我們的H5的容器叫(jiào)做Nebula。那麼(me)啓動了應用之後(hòu),我們這(zhè)裡(lǐ)面(miàn)就(jiù)會(huì)有一些像框架的生命周期的回調。MicroAPP的話對(duì)我們來說(shuō)就(jiù)有 onLaunch,onStart,onStop之類的生命周期的回調。那麼(me)Native這(zhè)一層的話,像Android的這(zhè)邊就(jiù)會(huì)有一個Activity像跟Manager和Fragment之間的被調用,然後(hòu)調用完之後(hòu)就(jiù)會(huì)創建一個頁面(miàn),這(zhè)個頁面(miàn)的話就(jiù)是我們的H5的容器的頁面(miàn),然後(hòu)它會(huì)有一些像腳本加載,像我們内置寫的一些插件的加載,比如說(shuō)你要對(duì)于一些請求,對(duì)一些業務的指标做一層監控的話,在這(zhè)邊寫一個插件是一個非常不錯的選擇。
我們對(duì)于外部的容器做的更多的事(shì)情,是希望我們的Native和外部之間有暢通的通信通道(dào)。在這(zhè)裡(lǐ)的話,我們演示PPT裡(lǐ)面(miàn)講的就(jiù)是一個JS Bridge概念。我們Native會(huì)使用EvaluateJavascript的方式,把JS的代碼傳到外端,web的這(zhè)邊會(huì)使用console的一些消息,把消息發(fā)回到Native這(zhè)邊,我們希望把web的體驗做到一個極緻,web體驗無非是幾個概念,首先是一個首頁的加載問題,然後(hòu)是不同平台之間的差異問題。最後(hòu)是一些離線資源的緩存的問題,那麼(me)在這(zhè)些問題之上,我們提供了這(zhè)麼(me)多的解決方案。
首先第一點,我們把網絡請求這(zhè)一塊的東西,從WebView的那一層去提煉到我們的Native的那層,因爲我們native對(duì)于網絡有更好(hǎo)的一些能(néng)力,比如說(shuō)我們可以使用除了HTTP和websocket之類的協議以外,做一些其他的協議的構建,那麼(me)同時(shí)也解決了一些跨越的問題。因爲 APP是受我們管控的,所以說(shuō)我們對(duì)于訪問的域名也可以做一些管控。那麼(me)在這(zhè)個基礎上,我們就(jiù)可以解決一個前後(hòu)端分離的問題。頁面(miàn)資源的話可以提早的去加載,那麼(me)對(duì)于前端來說(shuō),前端隻關心了他的業務數據的溝通。
第二點的話,我們提供了一個差量更新的一個能(néng)力,差量更新的概念是什麼(me)?比如說(shuō)我這(zhè)次去下發(fā)了一兆的離線包,然後(hòu)我發(fā)現以離線包裡(lǐ)面(miàn)有一些bug,那麼(me)對(duì)它做了一個修複,比如說(shuō)發(fā)布了一點1.0.1版本,那麼(me)兩(liǎng)個離線包的改動可能(néng)非常的小,比如說(shuō)隻有一個字符串改動或者說(shuō)幾行代碼的改動,這(zhè)個時(shí)候就(jiù)可以使用差量更新去把隻有改動的部分提交到我們的MDS發(fā)布平台,那麼(me)MDS會(huì)在合适的時(shí)機把這(zhè)一部分差量的數據量下發(fā)到我們的端上,那麼(me)端上根據差量就(jiù)可以自動合并出一個新的離線包。
那麼(me),用戶在下次打開(kāi)的時(shí)候,你的離線包已經(jīng)被更新了,那麼(me)這(zhè)個過(guò)程既可以使得流量的使用量變得很小,同時(shí)又能(néng)快速的響應業務端的需求。
第三點我們講的是一個推拉結合的概念,其實還(hái)是蠻有意思的一個點。因爲我們在傳統的HT模型裡(lǐ)面(miàn),我們永遠是一個拉的概念,我在客戶端提起(qǐ)這(zhè)request,然後(hòu)服務端去返回response,當然http2的話是有了serverpush的一個概念,那麼(me)我們不是說(shuō)是在serverpush上做了一個加強,我們本身有一個組件叫(jiào)做sync,對(duì)于mPaaS平台來說(shuō),它就(jiù)是一個穩定的長(cháng)連接。那麼(me),那麼(me)服務端可以通過(guò)長(cháng)鏈接、提前的向(xiàng)端上去發(fā)一些想要的東西,比如說(shuō)提前去發(fā)送離線包這(zhè)樣的概念,或者說(shuō)其他的一些數據,特别是基于事(shì)件的一些數據。
然後(hòu)第四點的情況就(jiù)是當我們的離線包發(fā)布如果失敗的情況下,我們可以設置一個fallback走線上的一個流程。這(zhè)個流程的話是防止我們的離線包下載失敗的時(shí)候所做的事(shì)情,這(zhè)一點是爲了做正确性的事(shì)情。然後(hòu)一個是我講過(guò)的獨立浏覽器内核的問題,可能(néng)在之前我們遭遇的情況比較多一點,現在的我們這(zhè)邊的話支持的版本還(hái)是在4.3, 4.4以上,還(hái)會(huì)存在一些問題,那麼(me)我們的離線包,我們的UC WebView是實時(shí)動态更新的,他并不跟著(zhe)安卓系統走,所以我們提早下發(fā)的更新可以幫助用戶更好(hǎo)的去穩定他們離線包的體驗和減少前端bug的産生。
後(hòu)面(miàn)一點的話,我們講的是一些深度自定義的組件,這(zhè)一塊的話,我們有提供了Ant Design之類的一些方案,可以讓用戶快速的介入去構造一個頁面(miàn)。那麼(me)最後(hòu)一點是監控。其實監控是在這(zhè)邊最枯燥乏味,但是是最重要的一個環節。因爲我們需要對(duì)于業務穩定性和本身的業務點做一些監控,那麼(me)這(zhè)些監控做完之後(hòu),我們就(jiù)可以快速的響應用戶的需求,去解決用戶碰到的一些問題,同時(shí)我們可以收集一些運營的數據,然後(hòu)對(duì)下一次産品的改進(jìn)和bug修複做提供非常有效的幫助。
我們H5的容器包含了非常巨大的擴展性,我們首先提供了一些JS的API,可以使H5的代碼有調用,Native的能(néng)力在前面(miàn)已經(jīng)說(shuō)過(guò)了。他不僅是一些普通的能(néng)力,還(hái)包括像數據存儲、全球廣播,然後(hòu)還(hái)能(néng)自定義的擴展API,然後(hòu)我們在Nebula容器上提供了一些容器的插件,容器插件的話,它是基于事(shì)件去響應的,我們在這(zhè)邊H5裡(lǐ)面(miàn)有提供了一系列的容器上的生命周期,那麼(me)當生命周期回調響應的時(shí)候,我們就(jiù)可以在插件中收到這(zhè)塊生命周期的事(shì)件。
那麼(me),基于這(zhè)個事(shì)件,我們可以去做出各種(zhǒng)各樣功能(néng),然後(hòu)開(kāi)關這(zhè)一塊其實是做ABTest之類的需求是最好(hǎo)用的一塊功能(néng)。那麼(me)我們可以在特定的條件下做一些開(kāi)關的配置,比如說(shuō)以人群,以機型,地域之類的方式去做這(zhè)些開(kāi)發(fā)配置,那麼(me)我們可以給特定的地域、特定的人群做提前的灰度,或者說(shuō)AB的能(néng)力。我們的H5的容器最顯著(zhe)的一個特性,是要比原生的WebView的穩定性要高出很多。這(zhè)邊我們有兩(liǎng)個指标,一個是PV的崩潰率,一個是PV ANR的概率,那麼(me)崩潰率就(jiù)是Crash率,那麼(me)我們這(zhè)邊的話比傳統的容器要高一倍以上,那麼(me)ANR的概念就(jiù)是你在劃的過(guò)程中卡死的概率,我們這(zhè)邊主要核心解決的兩(liǎng)個問題,是WebView穩定性和WebView體驗不一緻的問題。
Part2:監控+發(fā)布平台,滿足業務穩定運行、快速叠代
然後(hòu)講一下我們的監控和發(fā)布平台,因爲這(zhè)塊是圍繞著(zhe)我們H5容器的生态,需要去做到的一個非常大的後(hòu)端能(néng)力。首先第一點,我們需要有快速發(fā)布的能(néng)力,因爲我們知道(dào)基于原生的H5頁面(miàn),其實它是本身就(jiù)具有實時(shí)發(fā)布的,實時(shí)發(fā)布的概念就(jiù)是你自己如果擁有一台服務器,那麼(me)你去發(fā)布你的前端頁面(miàn)的時(shí)候,它是實時(shí)更新的。如果使用離線包的話,他的确是喪失一些快速發(fā)布的能(néng)力,但是我們在這(zhè)裡(lǐ)需要把快速發(fā)布的能(néng)力給他補償回來。
所以我們首先去接入我們的MDS的時(shí)候,我們的離線包首先是發(fā)布的MDS上,那麼(me)MDS會(huì)根據你之前配置的一系列的東西,去把我們的離線包發(fā)布到CDN上,然後(hòu)根據我們之前客戶端上的一些條件,比如說(shuō)你是否打開(kāi)了灰度開(kāi)關,或者說(shuō)是全網Release,如果是灰度開(kāi)通開(kāi)關的話,還(hái)需要根據你灰度的一些配置,然後(hòu)通過(guò)客戶端和服務端這(zhè)些客戶端和MDS之間的一些請求,然後(hòu)把我們的離線包的地址下發(fā)到客戶端上,那麼(me)客戶端會(huì)拿到這(zhè)個地址,從CPN上把我們的離線包下載過(guò)來,這(zhè)是我們的提供的一個快速發(fā)布的能(néng)力。那麼(me)快速發(fā)布既要擁有智能(néng)灰度的能(néng)力,同時(shí)也需要提供增量拆分離線包的能(néng)力,這(zhè)個能(néng)力對(duì)于客戶來說(shuō)是不可見的。因爲客戶隻用把兩(liǎng)個版本的離線包上傳到我們的服務端,我們服務端自動會(huì)算出這(zhè)兩(liǎng)個離線包之間的差異,然後(hòu)把差異下發(fā)到客戶端,我們同時(shí)需要保證我們的MDS的性能(néng)需要達到非常高的要求。那麼(me)我們的MDS的性能(néng)QPS可以達到5萬每秒,那麼(me)對(duì)于端的一個觸達率有達到99.99%。
然後(hòu)接下來講的是一個監控和診斷,那麼(me)監控其實是我們一個非常需要重點關注的維度,因爲我們把業務開(kāi)發(fā)完畢,去下發(fā)到用戶端的時(shí)候,如果用戶體驗非常不好(hǎo)的話,那麼(me)我們的留存率是非常低的。所以說(shuō)我們需要針對(duì)于閃退、流暢度、電量,流量之類的,還(hái)有不可用的一些一些業務都(dōu)需要做一些埋點。我們去埋點之後(hòu),就(jiù)是收集完用戶的一個使用情況的時(shí)候,我們需要去上報。那麼(me)如果做到實時(shí)上報的話,這(zhè)個上報的策略其實是不合理的。
因爲第一會(huì)影響用戶的體驗,因爲實時(shí)上報的話,我們可能(néng)一直開(kāi)著(zhe)一個進(jìn)程,或者說(shuō)還(hái)有一條線程去上報。第二,對(duì)于用戶的流量也會(huì)有非常大的影響。那麼(me)同時(shí)我們還(hái)需要考慮用戶在使用我們APP過(guò)程中的一個的情況,比如說(shuō)做一些定制化的開(kāi)關,或者說(shuō)需要做一些特殊的一些采樣。比如說(shuō)如果這(zhè)個時(shí)候一個用戶跟我們去報他使用APP的過(guò)程中産生的Crash,那麼(me)我們并不需要收集全網Crash情況,因爲用戶他自己的使用場景可能(néng)會(huì)比較特别,所以說(shuō)我們需要有對(duì)于特定的用戶有一個固定抓取的能(néng)力。
然後(hòu)我們上報的方式有有三種(zhǒng),第一種(zhǒng)就(jiù)是自動上傳,第二種(zhǒng)是周期性的檢查上傳,比如說(shuō)每隔一小時(shí)或者每隔一天。第三點是診斷指令驅動的上傳,這(zhè)個意思就(jiù)是我剛剛說(shuō)的一個場景,一個用戶報Crash了,那麼(me)我們需要用戶比如說(shuō)上報一下他的郵箱,或者說(shuō)賬号名字之類的,那麼(me)我們可以精準的在用戶手機上去抓取一段日志。那麼(me)我們根據用戶上傳的一些日志,我們可以進(jìn)行進(jìn)行頁面(miàn)的一個跳轉路徑的分析,然後(hòu)還(hái)有APP自己産生的一些日志做一些分析,那麼(me)分析完之後(hòu),我們就(jiù)可以做出一些決策,比如說(shuō)該怎麼(me)優化這(zhè)些東西,那麼(me)如果我們的Crash去和ANR的率到達了一定程度的時(shí)候,我們需要有熔斷的一些措施,比如說(shuō)把離線包的頁面(miàn)或者禁用掉,那麼(me)或者說(shuō)走fallback,或者走修複這(zhè)三個流程。
這(zhè)個是我們提供的四個能(néng)力。首先第一點的話是故障隔離,就(jiù)是說(shuō)如果我們發(fā)現這(zhè)個頁面(miàn)産生了一個故障的話,我們需要提前的去開(kāi)啓某個開(kāi)關,如果它是一個新業務的話,比如說(shuō)他開(kāi)關是開(kāi)著(zhe)的情況下,我們需要立即把它關掉,然後(hòu)屏蔽掉之後(hòu),進(jìn)行一個止血的過(guò)程。
那麼(me)第二點,如果我們的閃屏頁面(miàn)發(fā)生過(guò)程,因爲這(zhè)個時(shí)候用戶可能(néng)進(jìn)不了我們的APP,那麼(me)需要我們去進(jìn)一個安全模式,這(zhè)個時(shí)候需要對(duì)安全模式裡(lǐ)面(miàn)的一些數據進(jìn)行一些診斷上傳。然後(hòu)把我們的APP裡(lǐ)面(miàn)的一些數據清除掉,然後(hòu)再重新開(kāi)啓。這(zhè)個是一個自動恢複的能(néng)力。
第三點,我們是需要進(jìn)行一些流量的熔斷,比如說(shuō)我們的網絡調用到達一定請求或者說(shuō)一定程度大概率是出現在比如說(shuō)我們這(zhè)邊的服務器或者說(shuō)客戶這(zhè)邊的APP端業務端受到一個DDOS的一個場景,那麼(me)這(zhè)個時(shí)候我們需要對(duì)流量做聲做成(chéng)一個熔斷。
第四點就(jiù)是我們一個非常重要的動态化能(néng)力的修複。那麼(me)這(zhè)裡(lǐ)面(miàn)包含了好(hǎo)幾個内容,第一點是剛才之前說(shuō)的開(kāi)關。第二點是離線包的一個版本更新,我們比如說(shuō)前面(miàn)的離線包發(fā)生了一些問題,那麼(me)我們需要及時(shí)的修複、去上傳,然後(hòu)快速的全網發(fā)布。然後(hòu)第三點是基于原生代碼的一個Hotpatch,那麼(me)安卓上的Hotpatch的話,我們還(hái)是使用的是DexPatch的方案,那麼(me)能(néng)修複Native上的Java代碼,然後(hòu)他同時(shí)可以做到監控,可以回滾,在我們的mPaaS後(hòu)台去點擊一個回滾的按鈕,那麼(me)我們快速的把這(zhè)幾個下發(fā)的新的東西做一個回滾,因爲誰也沒(méi)辦法去保證自己下次寫的代碼沒(méi)有bug。
所以說(shuō)隻要我們如果驗證沒(méi)有問題,那麼(me)我們的修複可以發(fā)放,如果說(shuō)熱修複是有問題的,那麼(me)我還(hái)要做到一個快速回本,去發(fā)一個新的Patch,那麼(me)對(duì)于我們來說(shuō)的話,我們的Native發(fā)闆可能(néng)會(huì)做得比較慢,那麼(me)如果在我們上了H5的方案之後(hòu),那麼(me)我們H5的發(fā)版肯定是比Native的發(fā)版要走得快的。假設說(shuō)我們在一個APP裡(lǐ)面(miàn)有N個産品,那麼(me)他們之間的發(fā)展節奏像是這(zhè)個樣子,那麼(me)他們的整個産品的一個生命周期是左邊的一個環形的架構,其實還(hái)是蠻傳統的一個交流,首先的話是業務這(zhè)邊去制定目标,然後(hòu)開(kāi)發(fā)這(zhè)邊進(jìn)行代碼構建,然後(hòu)我們進(jìn)行一個灰度持續的監控,最後(hòu)正式發(fā)布完之後(hòu),我們進(jìn)行一個運維的監控,運維監控之後(hòu),我們再做一個灰度的驗證,然後(hòu)制定一個新的目标。
對(duì)于不同的版本的話,這(zhè)裡(lǐ)面(miàn)重點講的是一個灰度的概念。對(duì)于灰度來說(shuō),我們需要知道(dào)用戶這(zhè)邊的一些條件,比如說(shuō)我們這(zhè)次需要做一個基于安卓手機的性能(néng)優化的方案,那麼(me)我們需要去用條件去篩選出我們安卓裡(lǐ)面(miàn),比如說(shuō)CPU是骁龍600系列或者500系列的一個低端的CPU的話,然後(hòu)去驗證我們的這(zhè)一次的性能(néng)修複的包的表現。
Part3:更優異的 Hybrid 方案,HTML5 與小程序差異化解析
我們這(zhè)邊需要去講一下最近非常火的小程序的方案,小程序是在H5發(fā)解決方案之上更加升級的一個架構。
首先小程序是一個基于Web技術,然後(hòu)又集成(chéng)了原生能(néng)力的一個新的移動應用格式。那麼(me)對(duì)于小程序來說(shuō),跟H5一個最大的不同是H5本身其實是技術是開(kāi)放的,但小程序就(jiù)等于是給了一套完整的開(kāi)發(fā)框架。那麼(me)你繼續跟著(zhe)開(kāi)發(fā)框架和DSL編寫出了相應的業務代碼之後(hòu),然後(hòu)編譯成(chéng)一個小程序的包,然後(hòu)發(fā)到相應的平台上,平台可以根據你這(zhè)一套DSL去渲染出它的一個頁面(miàn),當然它的渲染引擎是可以随時(shí)更換的,不一定是WebView的渲染引擎,他比如說(shuō)可以根據 skia的渲染進(jìn)去寫一套基于skia渲染去做。那麼(me)小程序的優勢有四種(zhǒng),一個是獲取便捷,比如說(shuō)掃二維碼就(jiù)能(néng)直接去打開(kāi),他不需要你去架設服務器,不需要去考慮CDN之類的一些東西。第二個就(jiù)是小程序和小程序鏈接的一個能(néng)力。然後(hòu)還(hái)有小程序跟Native之間的一些連接的能(néng)力。第三個的話小程序的安全性和可靠性是由各個大平台去保障。第四點小程序的渲染,它是由你各個去指定的标簽去決定的,比如說(shuō)我可以使用原生的組件去渲染小程序上一些DSL的組建,在這(zhè)種(zhǒng)情況下,它的渲染能(néng)力反而是會(huì)比H5的渲染能(néng)力會(huì)更高一點。那麼(me)整個小程序的架構是像圖上這(zhè)樣子,小程序的渲染層和邏輯層是徹底分開(kāi)的。
大家可以認爲渲染層裡(lǐ)面(miàn)是有一個WebView有選擇,那麼(me)渲染才是WebView,那麼(me)實際上它的一些事(shì)件執行,像一些邏輯的執行,是開(kāi)了另外一個JS引擎去做這(zhè)個事(shì)情。那麼(me)它們之間通過(guò)Native層的一層JS Bridge進(jìn)行通訊,那麼(me)每次邏輯層把需要更改的配置的一些信息去成(chéng)立到Native層,Native層獲取到渲染層裡(lǐ)面(miàn)已經(jīng)渲染了的DOM信息,然後(hòu)計算出差分邏輯,最後(hòu)下發(fā)到我們的渲染層。那麼(me)渲染成(chéng)每次去更新UI的時(shí)候,都(dōu)是會(huì)把差異化的一些數據把它給渲染出來。那麼(me)在這(zhè)種(zhǒng)情況下,我們的渲染層和邏輯層之間的執行是完全隔離的,這(zhè)個是我們所講的小程序雙線程的一個概念。同時(shí)小程序因爲有平台的容器作保障,所以說(shuō)我們這(zhè)邊能(néng)快速的打通Native層的一些存儲網絡多媒體的能(néng)力。在這(zhè)種(zhǒng)情況下,我們使用小程序開(kāi)發(fā)的時(shí)候,可以用最少的成(chéng)本去開(kāi)發(fā)出性能(néng)最好(hǎo),動态能(néng)力最強的一個框架。
那麼(me)同時(shí)我們小程序提供了一個ID構建和發(fā)布的一個能(néng)力,ID構建的話,我們現在支付寶這(zhè)邊有提供小程序的IDE,同時(shí)開(kāi)發(fā)支付寶小程序,淘寶小程序,還(hái)有mPaaS小程序,它們三者之間雖然技術架構不太一樣,但是它們之間的DSL是相同的,你可以使用同一套代碼去開(kāi)發(fā)。那麼(me)Native這(zhè)一層,首先先對(duì)你傳遞的參數做一層解析,解析完之後(hòu)去提前加載小程序的資源,然後(hòu)去創建一個渲染頁面(miàn),比如說(shuō)這(zhè)裡(lǐ)面(miàn)Render我講了,目前來說(shuō)是基于UC WebView,但是它同時(shí)也可以不基于UC WebView,這(zhè)個對(duì)于業務來說(shuō)是完全沒(méi)有感知的,那麼(me)在渲染層初始化完畢之後(hòu),我們這(zhè)邊會(huì)創建了一個JS的worker,那麼(me)這(zhè)個worker就(jiù)是我們剛剛講的邏輯層的一個概念。worker創建完之後(hòu),會(huì)對(duì)于原先小程序裡(lǐ)面(miàn)執行的小程序JS代碼裡(lǐ)面(miàn)執行的一些事(shì)件做監聽,那麼(me)會(huì)回到小程序裡(lǐ)面(miàn)的一些事(shì)件的callback,然後(hòu)小程序的JS引擎裡(lǐ)面(miàn),對(duì)于業務代碼層面(miàn)上對(duì)這(zhè)些callback做出一些響應,比如說(shuō)Set Data之類的回調。調完之後(hòu),會(huì)傳遞到Native這(zhè)一層,Native這(zhè)一層把原先去更改的一些數據傳遞給渲染成(chéng)層,然後(hòu)渲染層在下一次事(shì)件循環中,把這(zhè)次傳的數據做一個差分的渲染,然後(hòu)做完之後(hòu),我們就(jiù)能(néng)看到我們想要的一個産品,那麼(me)這(zhè)個就(jiù)是我們剛說(shuō)的小程序的雙線程的概念。邏輯上在worker這(zhè)邊,然後(hòu)渲染層在Render這(zhè)邊。
小程序的特征是非常規範的提供了這(zhè)麼(me)幾個能(néng)力,首先第1個包體的構造是在一個标準要求之下的,我們必須提供這(zhè)樣的一個包體的結構,然後(hòu)UI組件和API是另外提供的一個能(néng)力,然後(hòu)入口規範的情況下,我們能(néng)快速的把我們小程序的内容和小程序的整體的頁面(miàn)的管控,收斂到一個比較小的口子上,那麼(me)能(néng)最大的防止各種(zhǒng)風險。
同時(shí)它的安全和隐私的管控,在于我們的Native的容器裡(lǐ)面(miàn)已經(jīng)包裝好(hǎo)了,比如說(shuō)小程序想獲得一些隐私相關權限的時(shí)候,需要我們的Native這(zhè)邊在UI層面(miàn)上作出一些響應,比如說(shuō)想要獲得用戶定位的能(néng)力,或者說(shuō)想去獲得用戶的手機号,這(zhè)些東西我們都(dōu)需要在Native這(zhè)一層去向(xiàng)用戶去申請權限。然後(hòu)同時(shí)我們又提供了一些小部件,小部件到是一個可以認爲是插件,或者說(shuō)是像UI組件這(zhè)樣的一個東西。
然後(hòu)我們的小程序的整個生态,目前來說(shuō),支付寶的mPaaS小程序有在各個地方都(dōu)使用,比如說(shuō)像餓了麼(me)、高德,淘票票之類的東西都(dōu)在用。
在這(zhè)種(zhǒng)情況下,我們把我們整個小程序能(néng)力做了一個封裝,通過(guò)mPaaS的一個方式去去分發(fā)給各個用戶。那麼(me)用戶去集成(chéng)了我們mPaaS的容器之後(hòu),也能(néng)基于這(zhè)一套生态去開(kāi)發(fā)出自己想要的小程序,然後(hòu)在自己的APP上進(jìn)行運行。我們希望我們正常開(kāi)放的生态環境,希望能(néng)讓用戶因爲小程序而受益。然後(hòu)也能(néng)擁有自己的一個動态化能(néng)力。我們希望能(néng)提升用戶的粘性,然後(hòu)連接海量的服務,然後(hòu)服務的話,希望能(néng)快速的觸達到多端。
然後(hòu)我們mPaaS是支付寶裡(lǐ)面(miàn)整合出了一套完整的引擎,那麼(me)我們mPaaS就(jiù)提供了好(hǎo)幾種(zhǒng)從服務端到客戶端的完整方案,那麼(me)對(duì)于客戶端來說(shuō),有提供客戶端的SDK和客戶端的框架。那麼(me),客戶端和服務端之間的連接,通過(guò)我們自定義 RPC協議,包括推和拉結合,推的話,剛剛說(shuō)的Sync組件,拉的話我自定義的HTPR的一些協議,那麼(me)mPaaS的中台還(hái)有提供網關,然後(hòu)把用戶的一些行爲數據進(jìn)行分析,然後(hòu)還(hái)有消息推送,然後(hòu)發(fā)布,還(hái)有開(kāi)關等等。
後(hòu)端的mPaaS的話是有一些計量計費的管控,然後(hòu)多租戶的管控,這(zhè)一塊是我們這(zhè)邊自己的一些能(néng)力。然後(hòu)整體的話我們mPaaS現在是基于阿裡(lǐ)雲去做的。
目前,mPaaS已經(jīng)上架到了阿裡(lǐ)雲對(duì)外輸出了,歡迎大家試用。