消息推送SDK如何保證穩定性和安全性?看看個推資深專家怎麼說

一個好的消息推送SDK應該具備穩定、易用、安全、小巧靈活等特點。個推作爲國內第三方推送市場的早期進入者,一直致力於爲開發者提供高效穩定的推送SDK。經過多年的打磨和創新,個推沉澱了豐厚的技術經驗。這期文章將從“小”、“穩”、“好用”以及“安全”四個角度分享個推推送SDK的技術經驗。

1 小

1.1 65535限制

好的消息推送SDK首要需考慮到包體的小巧靈活性。爲什麼選擇更小體積的包體?從代碼層面來看,是由於系統的“65535限制”。如上圖(左)所示,我們的程序最終會生成dex文件,dex文件主要由以下幾部分組成:header(標頭)、一連串的ids(標識符列表)、data(數據區)以及link_data(靜態鏈接文件中使用的數據)。細看上圖(右),它包含了一個method_ids_size字段,該字段的主要作用是定義個數。根據谷歌的定義,uint是一個16位的short類型,最長長度是65535。如果將dex工程反編譯,會生成很多smali的文件,再去看smali裏的函數調用(比如invoke direct {***} 函數名@BBB),會發現調用的地址其實就是剛纔unit裏定義的偏移量計算得出的。因此,這個函數地址最多也只能有65535個。

1.2 如何使包體體積變小

如何減小包體的體積,可以從以下幾個方面考慮:

(1)自研,不嵌套:在研發SDK時,不建議開發者在SDK內嵌套一系列框架,例如三方網絡框架、db框架或任務調度框架等。我們主張開發者選擇最核心的一部分進行自主研發。

(2)代碼優化:從算法層面,在效果相同的情況下,可適當減少代碼的行數;對於有默認賦值的變量不需要進行初始化賦值;選擇合適的字符串拼接方式,建議使用StringBuilder方法拼接字符串,可以解決字符串頻繁修改帶來的內存消耗,也有利於減少包體體積大小。

(3)追求實用,放棄完美:SDK包體應當追求實用性,以完善主功能爲主,其他相對次要的部分可以適當減少時間或精力投入,放棄完美主義思維。

(4)代碼混淆:藉助代碼混淆實現更小體積的包體,且不易被逆向。

1.3 省電省流量

省電省流量是“小”的另一個方面。作爲一款好的消息推送SDK,應該對流量和電量有嚴格的限制,否則會出現手機發燙、高耗電提醒、流量浪費、內置SDK APP難以上架等問題。針對上述問題,我們可以通過Lock殺手,智能心跳、自定義協議、鏈路合併、按需活躍等方式儘可能地降低SDK對電量以及流量造成的消耗。

(1)Lock殺手:代碼中WiFiLock、WakeLock等會強制喚醒APP,導致APP產生較大耗電量。在不影響功能的前提下,我們應儘量減少或者不用該類鎖。

(2)智能心跳:應根據不同的運營商、網絡狀態等,選擇不同的心跳策略,並且根據不同的應用場景探索心跳的最大邊界,儘量延長心跳週期,減少電量和網絡的消耗。

(3)自定義協議:市場上常用的json、xml、甚至PB協議,都有比較好的兼容擴展性,但同樣也帶來了空間浪費的問題,自定義協議可以充分利用空間,精確利用每一個byte甚至bit,極簡化封裝,承載最大的信息量,減少流量和電量浪費。

(4)鏈路合併:當一個設備有多個APP的推送鏈路同時活躍時,我們會運用合併鏈路技術,將使用“個推 SDK”的 APP 之間的長連接鏈路進行合併,減少流量電量的浪費。

2 穩

2.1 提升穩定性

在實際應用中,開發者可能會遇到ANR、OOM、Crash、內存泄露、閃退等棘手的問題,爲了打造好的消息推送SDK,我們需要通過持續的迭代和優化來將錯誤最小化。

(1)做好代碼管理:除了藉助SVN、GIT等工具做好代碼託管外,開發者還需遵循一定的代碼規範,藉助類似gerrit等工具進行代碼review,使用verify流程。在保證機器找不到問題的前提下,再用人眼去辨別是否符合業務邏輯。

(2)自動化測試:自動化測試可以大幅提升迴歸測試的效率,非常適合敏捷的開發過程。此外,自動化測試可以替代大量的手工機械重複性操作,測試工程師可以把更多的時間花在更全面的用例設計和新功能測試上。

(3)運用代碼模塊化等小技巧:代碼模塊化能以最少的模塊、零部件,更快速地滿足更多的個性化需求。異常處理可以提高系統的容錯性,讓程序更加穩定。代碼檢測能及時發現程序中的缺陷和錯誤,比如檢測內存是否泄露,是否有安全漏洞等,保證代碼質量。

(4)線上灰度:實際場景中,我們很難去覆蓋所有的環境,例如機型、網絡等,需要通過線上用戶的反饋去驗證代碼的健壯性。因此在產品大規模推向用戶之前,我們需要進行少量的真實用戶測試,即灰度上線來幫助減少風險。

(5)日誌系統:系統有問題是必然的,在儘量保持系統穩定的前提下,要考慮容錯性。當問題發生時,需要第一時間以最快的速度排查,因此需要有一套完整的日誌系統。此外,平時我們也可以通過日誌系統的撥測檢測系統的健壯性,可以在用戶反饋之前及時發現並解決問題。

2.2 兼容性

兼容性也是保證好的消息推送SDK穩定性的一個重要條件,主要考慮以下幾個方面:

(1)接口兼容:每次版本更新後,對外接口要儘可能保持不變。對於改動較大的接口,可以使用 @Deprecated 註解對老接口進行標記,並且做新接口調用的兼容,而不是直接刪除老接口。

(2)主鍵兼容:當主鍵發生變更(例如去掉service、provider)時,部分老的安卓系統會有組件緩存,運行時直接告知“類”找不到。建議在AndroidManifest中保留聲明,且對應“類”進行代碼空實現,以減少發生crash的概率。

(3)安卓系統兼容:可使用Build.VERSION.SDK_INT做API區分。

(4)真機兼容:可以藉助雲測等平臺進行兼容性測試。

3 好用

SDK的易用性可以從下面幾個方面考慮:

(1)接入簡單:接入SDK時有集成demo直接可以運行,且接入文檔清晰、步驟簡單,最好能實現一鍵集成。

(2)保持核心優勢:一款好的消息推送SDK,我們主要考慮及時性、到達率、穩定性和準確性。例如,新聞媒體類APP對推送的及時性要求較高;通知類推送(如轉賬信息)會特別注重消息的到達率;穩定性指的是要保證推送SDK在不同環境下的正常運行,尤其是11.11等高併發場景;準確性主要針對廣告營銷類推送,需要在合適的時間、合適的地點和合適的場景把合適的內容推送給合適的人。其中,關於如何保證穩定性,可以從多線路、多IDC、熱備份等角度考慮。① 多線路調整:例如預埋三線域名,做一些輪詢策略,防止域名被劫持。② 多IDC設置:除了域名被劫持外,還可能遇到網絡攻擊,物理性損壞的情況。設置多IDC一方面是爲了實現分流,另一方面也降低了風險。③ 熱備份:系統處於正常運轉狀態下的備份,一旦系統出現問題,可以快速恢復。

(3)多樣化需求:通過豐富的畫像標籤,對用戶進行場景化的智能推送,滿足用戶的多樣化需求。

(4)策略可控:我們還提供靜默時間、推送控量、短信補量、定時展示等附加功能,滿足客戶的實際使用場景。

$4 安全

SDK開發過程中,我們還需要注意安全性。安全性不僅僅代表網絡數據交互的安全、本地數據存儲的安全,也涉及到 SDK 的加固、混淆、第三方安全軟件審覈等。

其中,我們重點講解SDK的加固。目前安卓平臺SDK絕大部分都是Java語言編寫,容易被反編譯。SDK如果只是進行了簡單的混淆,很容易被窺探到內部實現細節,此外還可能存在SDK被二次打包、植入惡意廣告等現象。因此,我們需要對SDK進行加固,以提升安全性。

如上圖所示,SDK的加固主要是Java層面和so層面的操作。Java層面可以進行SSR IR指令轉換或者做Java2C處理,把實現細節放入native中;so層面可以做一些扁平化、虛假控制等來混淆代碼,也可以通過指令替換、指令跳轉邏輯來增加逆向難度。此外,也可以通過常量字符串加密加固SDK,這是目前較爲簡單實用的一種方式。

總結來說,其實開發一款好的消息推送SDK並不難,難的是如何讓自己開發的SDK在複雜的環境下穩定運行,這需要我們對 SDK 的架構有比較清晰的認知,並不斷迭代和優化。希望本文能爲各位開發者在實際操作中提供一定幫助。

關注我獲取更多知識或者投稿

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