客戶端HTTP請求優化實戰

轉自 https://zhuanlan.zhihu.com/p/31927387

一、引言

對每個APP來說,網絡請求必不可少,雖然有大把現成的框架能幫助我們輕鬆的完成這項工作,但是實際考究效果時,會發現經常有用戶反應請求很慢,頁面刷不出來,菊花轉不停等問題,可見其中還是存在不少優化空間的,這篇文章就燙爺在項目中對HTTP請求做的優化,做一個簡單的梳理。

二、數據採集

要解決問題,必先分析問題,要分析問題必先採集數據,所以要解決HTTP請求的問題,首先還是要想辦法獲得相關的數據,進而分析短板,針對性的進行優化。

獲得數據的方式有幾種,一者可以使用某些第三方sdk,嵌入後就可以在第三方的網站上看到HTTP請求的信息,錯誤日誌等,用起來雖然方便,但我不是特別推薦,因爲這些sdk爲了獲取請求信息,往往對客戶端的侵入十分嚴重,甚至經常會造成一些兼容性問題,影響app本身的穩定性,有時候頗爲讓人頭疼。

燙爺在項目中採用的是自己採集數據的方式,對請求框架再封裝一層,採集一個請求的完整信息——

  • 請求ID
    給每個請求生成一個唯一的id,可以方便同時在服務器端跟蹤這個請求,另外當請求重發時也可以便於服務器處理請求的冪等性
  • 請求URL
  • 當前時間戳
  • 用戶ID
  • 設備信息
  • 當前網絡狀態
  • 請求用時
  • 錯誤原因(如果請求出錯)

另外一點需要注意的是,這些信息採集完必須先存放在本地,因爲出錯的時候網絡狀態不穩定,很可能當時是無法上報日誌的,存在了本地,就可以尋找合適時機上報,不怕丟失信息。

三、錯誤數據分析

數據採集完了,經過分析發現了幾個顯著的問題

  • 請求錯誤中有相當大的比例在DNS解析時就已經錯了
    一個http請求的全過程簡單來說如下
域名解析 --> 發起TCP的3次握手(客戶端發起連接請求、服務器允許請求、客戶端確認) --> 建立TCP連接後發起http請求 --> 服務器響應http請求

所以域名解析是第一步,這一步出錯,後面就無以爲繼了。很多人會很奇怪,DNS解析這麼基礎的服務難道還那麼不穩定,還經常出錯?很不幸,DNS解析就是這麼不穩定。

  • 應用開啓時調用的那幾個接口是錯誤率最高的
    這其實也可以理解,很多安卓手機性能低下,在應用啓動時同時多個接口一起請求,造成了系統資源的緊缺,進而導致了錯誤率變高。
  • 網絡狀態不好時,錯誤率高
    這是一句廢話,但是也應該針對這種情況做一些相應的處理。

四、問題處理

DNS解析問題
dns解析異常的處理也有幾種方案,但總體的思路一致,就是既然域名解析異常,那我就不用域名解析了(好光棍的方法)。簡單來說有以下幾種方案,當然實戰時可以幾個方案同時使用。

  • 使用HTTPDNS之類的技術方案解決
    HTTPDNS說白了就是用HTTP協議進行域名解析,替代現有的基於UDP的DNS協議,避免域名解析失敗,域名劫持等問題。
  • 客戶端和服務器之間保持長連接,使用socket通信
    這在IM、推送sdk、遊戲中應用很廣
  • 本地維護一個ip列表,直接使用ip進行請求,而非用域名,並定期去服務器更新這個列表。
    同時還可以週期性的ping一下列表上的ip,動態選取延遲最小的ip。

實際在項目中我們採用了騰訊的wns服務,wns基本是結合了1,2兩種技術手段,起到的效果非常不錯。但是這裏提一句,wns並非騰訊的主營業務,所以支持度並不好,如果不是在騰訊內部有人,恐怕也很難用好wns,建議去尋找別的類似的第三方服務替代,或者乾脆自己實現。

接口優化

  • 在業務層面儘量合併接口
    如前所述,在app啓動時同時調用多個接口造成了資源擠壓,進而導致錯誤率上升,那我們就有必要在業務層面去推動合併接口。在自己的項目中,燙爺就把啓動時調用的7個接口合成了一個接口,一方面減少了客戶端的資源調用,降低了錯誤率,另一方面也減少了對服務器的壓力,一舉兩得。
  • 自動重發機制
    由於網絡的抖動,接口請求錯誤不可避免,所以針對某些錯誤碼,進行接口的自動重發,這樣雖然實際上不能降低錯誤率,但卻可以有效降低用戶體驗到的網絡錯誤,對用戶體驗來說還是很有幫助的。
    自動重發在客戶端層面不難做,更多的工作量其實在服務器側,服務器必須保證接口的冪等性,比如客戶發起了一個買入1000元產品的請求,第一次服務器雖然收到了請求,但因爲種種原因沒有返回客戶端,導致客戶端又重發了一次請求,此時服務器雖然收到了2次請求,但絕對不能去買2次1000元的產品。
  • 針對不同的網絡狀態動態調整timeout
    這個其實比較好理解,當發現用戶是4g或者wifi狀態下時,建議把timeout設爲12s左右,當檢測到用戶是在3g甚至2g狀態下時,大可以把timeout設爲30-50s。因爲用戶在較差的網絡下,是可以容忍較長時間的等待的,但是如果timeout卡死在了12s,可能每個請求都無法在12s內成功,這樣無論用戶刷新多少次都無濟於事了。

其他優化

  • 錯誤頁面
    當檢測到http出錯時,儘量彈出一個設計過的錯誤頁面,這遠比頁面一片空白要體驗友好的多
  • 網絡檢測
    更進一步的話,可以在錯誤頁面做一個網絡檢測,出一個網絡情況的報告,一來可以讓用戶自己發現問題,二來用戶可以直接把這個報告提供給在線客服,加速問題的定位,當然更重要的是讓用戶覺得我們對這個問題很重視,我們很專業;)

好了,針對客戶端HTTP請求的優化,燙爺大概就做了以上的這些嘗試,都不算特別高深,但因爲效果已經比較顯著,也就沒有進一步深入研究下去。最後說結果,無論是iOS還是Android,錯誤率從優化前的2%以上,降低到了0.3%以下,可喜可賀,可喜可賀~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章