天貓客戶端穩定性保障以及性能優化實踐

1002661109 8年前發布 | 11K 次閱讀 性能優化 軟件架構

手機天貓全局體驗組負責人吳發偉于APMCon 2016移動性能優化專場發表了題為《天貓客戶端穩定性保障以及性能優化實踐》的演講,現場解讀了天貓客戶端在穩定性保障方面的舉措,介紹如何從救火式的“消防隊”轉型到能夠及時的發現問題、預防問題的產生,以及解決客戶端啟動Crash的利器——安全模式是如何打造的。

架構演進

一開始天貓客戶端每一個端是一個同學在做開發,這個時候大家都很高興,所有人都愉快地進行開發。但是隨著無線占領市場,流量以無線為主,整個行業包括阿里也不例外,天貓無線會面臨各種挑戰,我們從一個團隊負責無線,變成多個團隊負責。其次,所有需求必須先在移動端上線,以前PC端長線需求必須轉到無線上面去做,并且需求也是成倍增加的。所以這個時候很多同學其實是從后臺或者其他的角色轉過來做客戶端的。相對來說他們就算客戶端研發新同學,在這種情況下我們如何保障產品的穩定性呢,這個是我們面臨的一個很大的挑戰。

為什么說架構上要做改造?第一,支持多團隊的研發節奏。第二,負責穩定性同學發現一個問題,如果版本發布要很久,這時遠水解不了近火,提升版本的研發迭代速度非常重要。我總結兩個詞語, 第一個對于我們來說研發效率,第二是用戶體驗

所以,我們做架構改造之前有這些問題,第一個 開發階段沖突非常多 。因為大家都會同時改一個地方和模塊,開發階段 編譯時間也是耗時比較 久。第二, 發布周期特別長 ,這個時候是捆綁式研發模式,只要有任何模塊的業務方出現問題,我們整個版本就發布不了了。第三,線上質量怎么樣去保證?所以,架構改造勢在必行。

做架構改造有一些原則,這里簡單介紹一下。

第一,算法導入里面提的分而治之,一個工程說是所有人負責事實上是沒有人去具體負責。所以,很重要一個點就是一定要劃分模塊, SRP就是The Single Responsibility Principle ,單一功能職責。

第二,就是業務模塊的 Bundle化 。天貓業務模型跟大家說一下,這個里面有首頁,搜索,店鋪,還有購物車,下單,物流等等這么多業務模塊。我們架構怎么樣去拆分?橫向是按照功能拆分,第二,就是按業務劃分,把首頁的相關電路模塊劃分到首頁團隊去,這就是康威定律。

接下來提一下架構改造用到的一些工具,模塊解耦中有跳轉協議、Rewrite、Beehive。從首頁到商品詳情最下面就是更多的驚喜,直接點一下就可以了。我們要保證研發速度快,怎樣解除依賴?我們會通過一串URL跳到對應的時候,需要根據報的結構跳轉過去。第二點是 Rewrite ,我們有多個跳轉目的地時,當線上一個地方出現問題,可以通過它來指到另一個目的地。第三,Beehive做模塊解耦。

關于依賴管理工具,這里大概畫了一個示意圖。

在改造之前就是這樣一個單工程架構,當然架構有一些分層。我們所有的業務都是在上層,UI都是在一個工程里面開發,右邊是容器化的架構,各個業務團隊可以依賴于這個業務容器進行獨立的開發,研發好測試通過就可以及時地進行發布。通過這樣的改造,可以做到按業務進行快速迭代的能力。改造之前,大家都是捆綁式的,但是,做了這個架構改造以后,我們就支持多團隊開發并且能夠做到想發布隨時發布,隨時進行拉分支,把要改動的業務模塊做一個集成。因為我們各個SDK都是有版本的管理,如果說有問題,我們把它弄掉就可以了。

中間的BUS層就是跳轉協議,還有Rewrite,Beehive。同時,我們也對之前的一些邏輯,包括一些輔助功能,把它抽離中間鍵,將一部分功能做了合并,這樣有利于安裝包縮小。

穩定性保障

穩定性保障,上一個架構改造舉措目的就是提升迭代速度,一開始負責穩定性的時候就會比較痛苦。舉一個例子,當線上出問題的時候,你現在修改了,發布版本需要至少幾天甚至兩周的時間。如果真的是很重大的問題,像你負責的APP到消費者手中因為緩存沒有辦法啟動了?怎么辦?有沒有同學碰到這樣的問題?所以說負責穩定性同學很辛苦,他們默默做很多的工作,應該多鼓勵一下。

我們一開始也是碰到這個情況,面對這種方式最開始我們覺得就是采取救火式,著火了我們就去解決,其實應該建立比較好的機制去杜絕,甚至各個環節去解決這個問題。我這里介紹一些相關經驗。

按照我們的一個研發周期,去把它拆成幾個環節,比如說 開發,測試,灰度,線上,還有線上的監控

我們把以前線上Crash上報,再去分析下一個版本解決的方式。用形成閉環的方式去解決一些問題,比如說,在開發階段有這些舉措。 第一,Code Review 第二,預置開關 ,很多新功能上線的時候,你做一些hook,做一些前瞻性改動,可能不是特別的確定,這個時候需要開關,如果沒有開關碰到一些狀況,一定會出問題。 第三,靜態掃描 。出現問題,我們不光靠人,是通過機器、工具,總結出來一些規則沉淀成代碼,把風險點掃描出來,并且要及時通過郵件短信的方式進行報警,防止破窗效應。 第四個就是動態檢測

第二個環節: 測試 。一般出問題都是來自于變動,變動對于客戶端來說很多時候就是服務端response,比如說接口定好了,反饋的字段都是協商好的,大家都拍著胸脯說不會再有變化了。但是,出現變化的時候,可能服務端接口變了,字段缺失,類型也變化了。這種問題怎么去避免呢?在測試階段我們也研發了相應的工具,我們會模擬服務端各種接口,數據,測試客戶端,讓它在各種異常情況下也不會發生問題。

第三個環節: 灰度 ,這個非常重要。就算開發測試階段再怎么測試,團隊人手都是有限的,怎么樣去把這些問題更多地暴露出來?我們有渠道包,有內部一個企業包去測試,去發現這些問題。

這個階段發現問題以后,去做好修復以后再發布到 線上 ,這樣的話質量可以得到比較好的保證。在線上,我們也是比較早開始就有這個技術了。然后我們還研發專門解決啟動問題的安全模式,在去年雙11之前就已經開始做了。還有客服端一些調試工具,便于發現問題。另外就是問題反饋,線上用戶及時反饋對于我們來說也是非常重要的環節,人多力量大,移動互聯網每個環境都是不一樣,用戶的及時問題反饋也是非常重要的。

監控 這個環節非常重要,我們負責穩定性的同學會對數據進行監控,配置實時報警。比如說看實時Crash,原來基準線可能是5次,當它發生到10次的時候,我們就會收到短信,甚至是其他方式的及時報警,如果是Crash次數上升,范圍會擴大,更多同學會收到報警,我們通過這種監控方式去及時發現問題。發現問題以后通過一些開關,包括修復手段把問題解決掉。但是,就算你考慮的再多方面,難免會出現一些故障。碰到故障以后,我們會進行故障的Review,把這一類問題甚至把這個故障為什么發生所暴露出來的各個環節去認真地討論清楚。討論了以后,不是為了定誰的責任,而是讓大家明白問題在哪里,下一次如何去避免?我們是通過這些故障的Review,把這整個環節里面的措施一點一點補齊的。還有一部分就是Crash的定位,經驗沉淀。定位Crash工具有很多,包括上報,分析等。負責穩定性的同學會把潛在一些風險點注意到,保證下一次不發生。通過這種方式,我們對于穩定性形成了一個閉環,下面對于其中一些環節重點做介紹。

開發階段,需要重點介紹一下。動態檢測,非主線程UI代碼可以及時在開發階段發現問題。靜態掃描,凡是編譯器報出來的OOM,我們一定必須去解決的。報警比較多,我們花時間把它梳理一下非常重要。防微杜漸,有一個效應叫做破窗效應,一個窗戶破了,過一周看一下,其他更多地方都破了。所以,一定把任何的細節問題在開發階段都杜絕掉,不要留隱患。

接下來就是配置中心。天貓客戶端有非常重要的基礎設施,我們會按照客戶端類型,每一個版本都有配置。開發的時候,潛在有一些風險要上線了,我們都給它加上一個配置,開發人員自己形成一個習慣了。因為我們經常做這樣的技術分享,加一個配置非常簡單,首先寫一個判斷就可以了。最后在服務端,在后臺我們把相應的配置加上去。

第一個就是Code Review。為什么要做Code Review?首先第一個問題在開發階段解決是成本最低的,而且效率最高的。用Code Review不只是為了穩定性,還可以保障我們的代碼可維持,架構也會得到不斷的梳理和完善,第三個是我們能夠對整體一個概況產生更直接的了解,還有可能我們有時候寫代碼會覺得,有別人看就可能寫的優雅一點,讓別人欣賞我們的代碼。第五點,保證團隊當中至少兩個同學懂這一塊代碼,這一點非常重要。我分享一個案例,一個國外做游戲視頻直播的公司,他們團隊3個技術同學,每一個同學負責非常大一塊功能開發。恰好團隊當中有一個同學要出去旅游,美國人都比較瀟灑,報一下老板也會批,休假了之后這個時候恰好碰上一個網紅,在網站上直播,服務器掛了。只有那個同學懂,這個時候怎么辦?最后問題很簡單,那個同學重啟機器就解決了。

所以,我想舉的例子就是這樣。尤其是團隊和產品經理,這一點非常重要,團隊同事很重要。團隊不要出現單點,一定要有備份。這樣的話,團隊同學包括TEL,大家都是可以為整個的客戶端的穩定性做出很好的保障。

最后一點,Phabricator。就是團隊肯定有很多的安卓工程師,有很多的專家,所謂專家就是把所有錯誤都是犯過一次,或者看別人犯過一次的人。怎么樣把這種經驗傳遞下去?分享肯定就是要做的,但是那個頻率不會特別高。如果讓新同學把之前犯過的錯誤,把一些功能問題上去了再改這個成本非常高。通過Code Review就可以使得新的工程師經驗得到快速成長。有的時候,相互做Review的時候,被Review的同學也是可以提一些很有趣的觀點給一些資深的同學。所以,這個東西是使得團隊的成員每一個人的經驗,能力都可以得到提升。

這里有一個數據,大家可以看一下。

Code Review不是說寫了代碼我們去審查,而是在設計方案的時候同時在審查方案可不可行。大家可以看一下。通過Design and code inspections可以提前發現60%的問題。我們花很大力量去做單測只能解決20%,但是在前面做這些事情,成本更低,效果更好。Code Review在工業界的做法,硅谷,非死book,還有谷歌都是非常嚴格的去執行的。

現在我們團隊已經有一半同學會去做提交前的Review,還有一些同學就是做提交后的Review,接下來就是推動讓所有同學都做到提交前的一個Review。

說下我們的線上運維。我們把一個事件處理定義成這樣幾個階段。 第一監控,第二報警,第三解決,第四預防 。第一,我們會有一個專門的平臺,整個平臺共用一套基礎設施,可以把用戶的Crash日志,包括Crash的數量、用戶數,Crash率都在這個平臺上面做處理。有問題的時候超過一定閾值,通過集團內部一個工具,叫做Xflush,它的目的就是為了監控報警。第三個階段,就是修復它了,修復的手段就是剛剛講的,第一就是修復工具,比如說iOS、安卓的一些修復手段。第二就是安全模式,一會兒介紹一下啟動階段的安全模式設計。第三個就是配置中心。第四個預防,通過這樣一套體系來做線上的運維。

下面介紹一下天貓客戶端安全模式,我們的1.0就是去年10月份做的,當時是重大活動一個前夕,壓力很大。但我們還是在比較短的時間做出了1.0版本,就是用來解決啟動的問題,當時設計兩級安全模式,第一級安全模式的原理,我這邊介紹一下。

這個思路還是比較的簡單,短時間連續Crash的時候,第一個動作是進入第一級安全模式,就是把關鍵點清空。從安卓市場下載APP第一次啟動沒有問題,有問題肯定也不會發出去。導致問題的一般來說都是服務端下發數據,第一步清除關鍵目錄緩存,我們會讓它正常啟動。這個時候如果還是發生Crash,我們就讓它進入到二級安全模式。讓整個APP恢復到初始安裝狀態,把所有的包括非關鍵目錄的其他地方的文件都清空掉。同時支持啟動過程當中做熱修復,這一點很重要。就是緩存搞不定的時候,我們可以通過Crash、熱修復解決這個問題。

V2.0時做了更多的工作,比如說,安全模式在比較極端情況下,如果說你依賴很多SDK,我們做了一個解耦,把對于其他的SDK依賴全部解耦掉了。并且1.0的時候還有一個界面就是提示用戶點此修復,我們再去修復這個問題。但是在2.0時開始做了一個無感修復。用戶看不到這個頁面,我們在后臺默默把這些問題解決掉。因為在這種情況下快速解決問題才是最重要的。

然后,3.0版本我們做了SDK化。之后的4.0我們支持了灰度,并且支持測試。還有一個支持業務定制。舉個場景講一講支持業務定制什么意思?假設APP不是啟動的Crash,啟動之后,點了首頁一個按鈕或者一個頻道,再到頻道里面才會加載一個緩存,但是,這可能就不算啟動Crash,因為它是普遍過一段時間,這種問題怎么處理呢?我們的一個設計方案支持在啟動階段對于特定業務一個緩存做清除操作,在服務端增加目錄地址,這個下一次啟動的時候,不點有問題的地方,就是在啟動階段把有問題的干掉了。

下面這個圖畫的比較抽象一點。

配置中心剛剛提到了,數據中心就是一些補丁之類的。測試,我們之前說安全模式很重要,所以做了以后就是會想,如果承諾做了安全模式,但是過了半年,安全模式不生效,我覺得這個是有問題的。一開始測試時間比較久,就是制造各種各樣的邊界條件,開始測斷斷續續需要4個小時。我們根據很多的場景做很多內部小工具,把這一塊工作簡化掉,現在這一塊的測試完成只需要10分鐘就可以搞定了,大幅度的提升測試效率。

大家覺得一周之中線上故障周一到周日哪一天故障問題數最少?我講一下答案。可以看一下這個圖。

經統計發現,周六線上故障出問題的次數最少。為什么?因為周六改動最少。所以,用一個詞,叫做no zuo no die,去改動很容易帶來一些問題。一個改動會帶來問題,下面的圖是按照周維度講的。為什么有兩周完全沒有故障;第一周就是12月最后一周,還有就是第二月第三周,這里直接講答案了。第一個是圣誕節的時候沒有問題,第二,是在幫同事做360度的績效評估,這個就沒有什么問題。所以,有一本書講的好,可以給大家推薦一下:《你的燈亮著嗎?》想改動的話,如果沒有想出三個點,說明對這個問題思考還不是很深刻。不可以說我這個完全沒有問題,但是可能還是不錯的。所以,我們制訂一個規則,就是在工作日期發布。這一點很重要。這個跟之前一些認知有一些變化。客戶端的話,我們要在工作日期發布,這樣就可以及時做回穩和處理,及時發現和解決問題。如果是周末可能找不到人。

灰度發布,這里是講配置的灰度發布。經過分析發現改線上配置,是導致出現Crash問題一個非常重大的人為原因之一,如果有配置中心,改一個配置全量生效的話,非常容易導致Crash。所以從經驗上來講,我們配置一定是灰度發布的。我們在業務快速上線,快速迭代的同時,iOS、安卓的Crash率做到0.03%左右。這就是一個穩定性優化的結果。下一個階段的重點,就是要解決Native Crash,包括iOS和安卓,還有OOM。

性能優化

簡單介紹一下新的優化舉措

Webview大家可以看一下,剛剛講過了,第一個就是WKWebview,第二個跟UC合作,安卓端用UC內核來做一個提升,用了UCWebview之后,速度提升了百分之十幾。還有就是圖片庫做了很多優化措施,尤其是移動端,在4G、無線網情況下,對于圖片的尺寸,屏幕大小,要根據屏幕大小做很多的裁剪、優化。網絡這一部分做很多的比如說請求合并,包括使用緩存,還有SPDY,我們現在是支持SPDY的。關于流暢度,我們根據不同頁面的情況對卡頓的地方做優化,把BS這一塊提升上去。啟動優化我們做了很多,比如任務分級,加載等等。最后一個是安裝包瘦身,瘦身了之后,有一個業務會上去,這個是循環變化的過程。降下去了以后,過一段時間又上去了,這個是持續做的。

這里對穩定性和性能優化措施做一個總結。

我們從救火式方式到形成閉環體系化方式去解決問題。就是用這樣幾個詞語,預防,監控,解決,報警。每一個環節都是可以梳理做很多的自動化測試工具和經驗沉淀。中間有一句話: Move fast with stable infrastructure 。我們要在快速迭代的同時保證基礎架構的穩定。

 

 

 

 

來自:https://blog.tingyun.com/web/article/detail/1191

 

 本文由用戶 1002661109 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!