蘇寧11.11:蘇寧易購移動端的架構優化實踐

Jac76J 8年前發布 | 11K 次閱讀 軟件架構

雙11,不僅是廣大商家和消費者們的饕餮盛宴,同時也是各家電商公司的技術研發力量的實力體現。為了給用戶帶來更好的體驗,蘇寧易購移動端團隊一直以來追求 “極速、穩定、安全” 的目標,圍繞這一共同目標,我們以小團隊作戰、敏捷的開發模式,開展了一系列工作,其中主要包括:

(1) 客戶端架構解耦 :為了保障App性能的穩定,適應業務的快熟發展及模塊化,我們完成了客戶端架構的改造,實現了系統橫向和縱向解耦、動態化、組件化等。

(2) 客戶端性能優化 :為了追求更好的響應性能,同時兼顧移動端安全性,我們進行了圖片渲染、靜態資源上的全方面加速,并且對網絡鏈路進行了深度的優化。

(3) 監控體系 :一切以數據為依據,實現了移動App監控和數據分析系統。

 

1. 客戶端架構的改造

蘇寧易購客戶端從11年開始做起,隨著移動技術的發展,架構也發生了很大的變化。

老架構的問題主要是代碼耦合問題:

(1)橫向代碼耦合——業務代碼之間沒有明顯的模塊邊界,哪里需要用到其它的功能就直接包含一下其它模塊業務的頭文件,生成所需功能的對象來直接使用,模塊之間調用呈網狀結構。

(2)縱向代碼耦合——由于沒有合理的進行縱向分層,很多基礎功能代碼里包含了大量的業務功能,業務代碼與基礎功能代碼沒有嚴格的邏輯界線。

圖1. 網狀引用結構:簡單的邏輯變的復雜且混亂

1.1 客戶端分層模型,解決縱向耦合

首先,我們對客戶端進行了分層處理。客戶端在縱向上劃分成三層:業務層、服務層、基礎層。在橫向上,我們引入了功能模塊的概念,將客戶端抽象為一個個的模塊所組建成的一個整體。分層思想如圖:

 

圖2.新架構下客戶端分層模型

1.   基礎層 :對基礎代碼做了很多整理,把基礎代碼里所有的業務代碼都刪除掉。另外我們自己重新封裝了數據庫、UI、網絡、自定義控件、常用的第三方庫、常用的自定義宏等內容,它們構成了我們的基礎層。

2.    服務層 :在基礎層成型以后,我們把一些通用的功能進行了封裝,例如:埋點、url管理、網絡狀態檢測、緩存管理等。它們使用基礎層來搭建自己的功能,為業務層提供服務。

3.    業務層 :對所有的業務功能進行模塊劃分,大致劃分為首頁、購物車、嗨購、會員、搜索等模塊,所有模塊都使用統一的真實目錄結構,將模塊從邏輯上和物理上都歸于一個目錄下,不同的模塊之間從物理上進行目錄隔離。

1.2 中介型引用結構,解決橫向耦合

解除橫向耦合的原理就是將之前直接的網狀引用結構改變為間接的中介型引用結構。加入一個模塊管理器,所有的模塊把需要提供給其它模塊調用的功能,都預先在管理器中進行注冊。在使用時,使用者向管理器進行申請,即可以得到對應的功能對象。在這種結構下,模塊的插拔對其它功能影響非常小,耦合也非常小,如圖。

圖3.中介型引用結構:調用邏輯清晰

在具體的實現方式上,目前常用的解耦方式大致有protocol方式和url方式,我們兩種都有用到:在對服務層的引用上,我們更多使用protocol方式;在對某些業務模塊的調用上,我們更多使用url方式。

protocol解耦:protocol方式是id的一種靈活使用,體現了面向接口編程的思想,模塊要導出的功能不是一個具體的頭文件,而是用protocol來表示功能的接口的.h文件。使用者在使用時得到的是一個id,但可以調用具體的協議方法來完成自己需要的功能。另外,由于得到的是id,所以功能模塊也實現了接口與實現的分離,例如根據不同的情況,被調用者可以通過id返回不同的實現對象,而使用者無需做任何變動。目前我們在埋點、定位、分享等服務層上使用的是這種方式的調用。

動態化和url解耦:隨著移動端架構的發展,出現了動態化的概念,即是把客戶端的部分功能在原生和H5、Weex、React Native等實現方式之間進行靈活的切換。這樣客戶端可以進行動態的發布、降級、切換實現等功能而不用重新發版本。易購客戶端里我們主要采用了url的方式來支持這種動態化。我們把需要動態化的原生頁面按業務線/模塊/頁面名的形式定義它的url,在頁面的類對象生成后注冊一個block到url跳轉管理器里,這個block會在使用者調用頁面url時被執行,生成一個頁面對象進行返回和展示,這樣就得到了url化的原生頁面跳轉。同理,H5、Weex頁面在客戶端也需要一個原生頁面作為容器來加載它們,因此我們把這兩個容器做為單獨的模塊,并且使用來進行跳轉。如圖:

圖4. url解耦模型

我們在url跳轉管理器上做了一些操作,它可以下載服務端的配置列表,根據配置列表來改變當前的跳轉方向,跳到不同的容器上來進行展示,由此我們也實現了通過服務端的配置來達到客戶端實現切換的目的。

2. H5容器的性能優化

在H5容器層面,我們也進行了多項的優化來提升頁面的加載速度,并且減少頁面的下載數據量。

2.1 靜態資源預加載

我們把前端頁面進行了動靜分離,把一些頁面會使用到的靜態資源預先下載到客戶端。把容器的資源請求進行攔截,將本地已經下好的文件內容返回給它進行展示,這樣就省去了即時網絡通信的時間,提升了頁面的加載性能。     

2.2 WebP圖片格式的使用

H5容器的圖片我們全部使用WebP格式。我們把容器對圖片的請求進行了攔截,用native代碼重新發起一個WebP圖片的請求,在請求成功后native把WebP圖片轉換為png的數據返回給H5容器進行展示,使用WebP后我們頁面需要下載的圖片數據量減少了一半以上。 

2.3 容器渲染性能優化

為了提升容器的渲染性能,并且解決H5頁面長列表內存不斷增大等問題,我們引入了Weex。Weex通過將js轉化為native代碼渲染,有效的提升了頁面的渲染性能,Weex提供的長列表實現機制通過native的單元格重用也很好的解決了長列表問題。我們把H5容器和Weex容器進行了動態化處理,通過url映射可以任意的在兩者之間進行轉換。

3. 網絡鏈路的優化

移動網絡環境與有線網絡存在著很大的差異與區別。因此,移動網絡對我們的性能策略優化提出了新的、獨特的要求。在我們未作優化前, 2G/3G網絡下一個簡單的資源(下載用時在0.1s)請求在網絡傳輸中可能都會耗費很長的時間(1.345s)。

圖5. 下載用時只占端到端時間很少的一部分

另一方面,隨著近年來蘇寧易購移動端的不斷發展和引流,用戶數持續遞增,網絡劫持的問題也逐漸嚴重起來,比如:頁面加載白屏,APP下端彈出小廣告,甚至無法提交訂單。保證移動網絡下,用戶隱私和數據傳輸安全性也成為了我們這些年來的重點工作之一。

為了解決性能與安全兩方面的問題與瓶頸,我們采用了以下技術方案:

3.1 使用HTTP/2——鏈路復用,加速傳輸

HTTP/2采用二進制幀格式而非文本格式進行傳輸,突破了請求并發數的限制,能夠實現完全的多路復用,使頁面的傳輸效率和建連復用效益最大化。我們在移動端部分促銷頁面使用了HTTP/2傳輸,在3G/4G/Wifi網絡下,其效果是令人欣喜的。

圖6. HTTP/2加速效果與HTTP/1.1對比

3.2 HttpDNS尋址——DNS解析安全、精確、快速

HttpDNS是使用HTTP協議向DNS服務器的80端口進行請求,代替傳統的DNS協議向DNS服務器的53端口進行請求,繞開了運營商的Local DNS,從而避免了使用運營商Local DNS造成的劫持和跨網問題。

在實現上,我們會維護一張域名列表,將域名解析值預取到客戶端本地的DNSCache中,預取優先調用HttpDNS接口,如果獲取不到數據,則直接從localDNS取數據,并設置一個獨立的線程作為定時器,根據TTL過期時間來檢查domain是否需要更新。

HttpDNS為我們帶來了安全和性能上諸多的收益。

3.3 HTTPS代理——保證傳輸鏈路的絕對安全

HTTPS能夠給用戶帶來更安全的網絡體驗、更好的隱私保護。然而,HTTPS增加了TLS握手環節,再加上應用數據傳輸需要經過對稱加密,對性能提出了更大的挑戰。作為一個好的架構,一定要均衡安全和性能兩方面,如果讓天秤向任何一方傾斜過多,都會影響最終的用戶體驗。

因此,結合服務端,我們做了很多優化工作:

(1)基于鏈路的優化

建立連接的延遲體現在每個SSL連接上,因此盡早完成SSL握手是優化工作的重點。對于普通的圖片資源和文檔請求,我們在CDN上完成SSL卸載;對于涉及用戶信息的受限資源和腳本,我們在內網防火墻上完成SSL卸載。

(2)基于SSL協議的優化

在SSL協議優化方面,我們在服務端支持ALPN協議,使用適合Forward Secerecy的加密算法,開啟了False Start,客戶端在第二次SSL握手的同時就可以發送應用數據,減少了一次RTT時間。

另外,我們啟用了Session ID和Session Ticket的會話恢復技術,對同一個用戶,在多個連接間共享協商后的安全密鑰。并將Session信息緩存到Redis中,通過一臺中心服務器統一管理,解決了集群情況下Session ID無法共享的問題。

(3)基于證書和加密套件的優化

在證書鏈優化方面,由于TCP初始擁塞窗口的存在,如果證書太長可能會產生額外的往返開銷,移動端采用的證書鏈都是“站點證書 - 中間證書 - 根證書”三級的,同時服務端只發送站點證書和中間證書,根證書部署在客戶端,將證書鏈控制在3KB以內。為了避免不必要的證書過期校驗,我們在服務端開啟了OCSP Stapling。

在加密套件的選擇上,優先選擇ECDHE-RSA-AES128-GCM-SHA256,綜合安全、性能和開銷,是最優的選擇。

當然,我們還實現了H5內容壓縮與圖片的智能適配,針對HTML、JS、CSS等格式進行無損壓縮;根據終端網絡制式智能調整圖片分發尺寸,提升終端展現性能。

經過我們以上的改造,從10大城市3大運營商上采集的數據分析,客戶端訪問速度提速明顯, Android大概提速一倍,IOS也有60%左右的提高;錯誤率也明顯減少了80%。

圖7. 安卓的加速效果對比

 

圖8. IOS的加速效果對比

4. 移動App性能監控系統

監控是系統的眼睛,尤其是針對線上電商系統。監控能讓我們知道系統的運行狀態,在我們進行優化時,監控能告訴我們優化的效果,在系統出問題時,也能讓我們知道系統發生了什么。可以說,一切都是建立在完善監控的監控體系下的,因此,最后咱們花點時間來聊一聊易購移動端的監控手段。

移動端監控體系既不能只看客戶端,也不能只看服務端,必須將客戶端、網絡,服務端相打通,形成完整端到端的調用鏈,才能讓問題無處遁形。

 

圖8. 蘇寧易購移動端端到端監控體系

我們開發了專門用于App監控和數據統計分析系統。能夠從五個維度:移動應用崩潰、移動應用錯誤、移動應用請求響應時間、移動應用交互性能、運營商網絡響應時間來幫助我們分析問題。

圖9. 蘇寧易購移動端平均響應時間監控

5. 結語

路漫漫其修遠兮,吾將上下而求索。經過了這些年來的努力,客戶端的架構升級讓易購App更加穩定的運轉起來,移動端加速各項技術的應用讓用戶體驗更加的極速和安全,再通過監控系統的全方位24小時實時監控和保障,真正做到了我們的良苦用心,用戶的暢快體驗。然而,追求極致的道路是沒有終點的,并且前行的過程中將永遠有挑戰,易購移動端團隊將繼續努力下去!

本文由 蘇寧易購移動端技術團隊 撰寫。蘇寧云商最早成立的完善技術團隊之一。面向蘇寧易購數億用戶群體,目前我們擁有一整套完備移動研發能力,在移動框架、性能優化、自動化測試、移動app監控及前端容器框架等各個方向已擁有近百位移動技術專家,在2016年818發燒節,蘇寧易購移動端占比已達到80%以上,我們致力于整合蘇寧線上線下渠道,立足于移動開發技術,擴展移動端優秀產品,為用戶提供極致移動體驗。蘇寧易購移動端技術團隊將會在移動端動態化,容器化,服務化等多方面深耕細作,并將會和廣大的同行朋友們一起,努力把移動技術越做越好。

 

來自:http://www.infoq.com/cn/articles/suning-11-11-mobileArch-ImproveAndPractice

 

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