安卓App穩定性之旅--記Crash率 <=0.1% 實踐
穩定性的意義
在移動應用性能方面,崩潰帶來的影響是最為嚴重的。
移動應用崩潰主要是由操作系統引發,是指應用在運行過程中出現的強制關閉(Force Closing)現象,從而打斷用戶正在進行的操作體驗。
應用崩潰可以造成關鍵業務中斷、用戶留存率下降、品牌口碑變差、生命周期價值下降等影響。
根據統計數據顯示,當iOS的崩潰率超過0.8%,Android的崩潰率超過0.4%的時候,活躍用戶有明顯下降態勢。
行業標準
Android行業標準:
- 優秀App:0%-0.2%
- 標準App:0.2%-0.4%
而作為一個有追求的技術團隊,我們追求一個有挑戰的標準:Crash Session<=0.1% 或者說Crash Free Session>=99.9%
:)
改進前
分析:
- Crash平均在0.3%
- 偶爾觸達0.2%
- 某時間段一度高于0.8%(不穩定)
- 從未達到過0.1%
評價:處于行業標準水平,偶爾有隱患版本發布
三板斧
-
磨刀不誤砍柴工:改進Crash上報系統
每個app都有Crash上報系統,手機證券采用的是百度SDK。而它不能將線上混淆后的代碼映射成開發代碼,因此很難定位問題。
因此我們將百度SDK替換成Fabric。
百度SDK:
imageFabric:
image -
第一板斧:解決Crash問題
現在的當務之急當然是解決已有Crash問題了。
image -
第二板斧:提高編碼質量
高質量代碼是穩定性的基石,在當前背景下(較多需求開發),我們有沒有工具能高效地幫助我們提高代碼質量呢?,能有立竿見影效果呢?
靜態掃描工具:Lint、Findbugs
-
Lint:安卓自帶的代碼掃描工具
通過它對Android工程源代碼進行掃描和檢查,可發現潛在的問題。
主要包括:xml文件中是否存在hardcode、unused resources、probable bug等等。
-
Findbugs是java的靜態分析工具
它檢查類或者JAR 文件,將字節碼與一組缺陷模式進行對比以發現可能的問題。
Findbugs自帶檢測器,其中有60余種Bad practice,80余種Correctness,1種 Internationalization,12種Malicious code vulnerability,27種Multithreaded correctness,23種Performance,43種Dodgy。
通過這兩個工具的掃描報告,可以找到很多代碼的邏輯錯誤、隱藏問題、性能問題等一般共性問題。
同時我們也要認識到這類工具的局限性。并通過自定義配置來避免“噪音”。
lint:
imageimagefindbugs:
imageimage -
-
第三板斧:灰度
測試遺漏問題就這樣放出去嗎?有隱藏bug怎么辦?
祭出王牌:灰度發布
所謂的灰度發布,簡單來講,就是不要一開始就讓所有用戶下載安裝應用,而是先覆蓋一小部分用戶!
發布不是簡單的從0到1,不是非黑即白,在中間有一個緩沖的灰色地帶。
通過灰度發布,真實用戶的真實場景測試,我們可以更全面、更深入的收集問題,修復問題。
隨著灰度覆蓋范圍的增加,暴露的問題也越來越充分,而當全量發布的時候,一定是一個穩定的版本!目前的策略:先在某一個渠道灰度,當問題暴露的足夠多時,再發布全量版本。
改進后
Never Stop
目標:長期穩定在<=0.1%
后續規劃的實踐
-
編程維度:
持續解決收集到的Crash問題
-
OOM和內存泄漏問題:
- 通過LeakCancary來檢測內存泄漏問題,并解決問題。
- 通過內存檢測工具來檢測內存占用情況,并優化問題。
- 通過技術選型,尋找更好的圖片管理框架。
-
編碼規范:編碼規范的重要性我就不闡述了
- 統一團隊內編碼規范,這里可以參考:阿里巴巴的Java開發手冊,站在巨人的肩膀上。
- 生成編碼規范的IDE(Android Studio)配置,工程師導入配置之后,可以非常方便的用快捷鍵 Reformate Code
- 使用靜態掃描工具CheckStyle和Lint來檢查代碼規范。
-
代碼重復度:
- 通過靜態掃描工具檢測重復代碼。
- 抽取重復代碼,提供工具類及底層基礎類。
-
復雜度:
- 框架升級:一個好的框架可以減少工程師的代碼量,提高效率。
- Kotlin:語言級的改進。簡潔的語法,以及NullSafty特性都是非常好的特性。
-
流程化及工具維度:
- 結對編程:主要是在前期設計和疑難模塊編寫時使用,希望取長補短,尋求更高質量的代碼。
- CodeReview:在代碼提交的流程上使用CodeReview機制。
- 在Jenkins中集成靜態掃描插件:findbug、lint、CheckStyle、PMD等。
-
測試維度:
- 充分的開發自測:自己寫的代碼,自己最清楚會有什么問題,開發自測發現問題的效率最高。
- 單元測試:
- 引入單元測試框架:junit、mockito、robolectric
- 靜態掃描工具:單元測試覆蓋率
- 兼容性測試
- monkey測試
-
發布維度:
-
灰度2.0
當前灰度策略其實還不完善,后續我們會提供一種更完善的灰度機制:根據用戶的應用版本號,手機型號,UUID等信息來選擇灰度的用戶,通過彈對話框的方式提示用戶升級。
這樣我們就能很方便的從多個維度來灰度,比如:Android7.0里面5%的用戶。
-
終極殺招:熱修復
通過熱修復技術,客戶端可以發布補丁來解決線上版本的穩定性問題,而無需發版本。
熱修復作為當下熱門的技術,在業界內比較著名的有阿里巴巴的AndFix、Dexposed,騰訊QQ空間的超級補丁和微信的Tinker。
-