網絡技術作爲互聯網應用賴以存在的技術基礎,速度與安全永遠是其核心使命,本次 WWDC 的網絡類 topic 涵蓋內容基本還是圍繞這兩個點來展開。本次 WWDC 網絡類 session 在基礎網絡技術上譬如新協議、新算法方面着墨並不多;也未提出新的類似 NSURLSession / Network.framework 之類的新網絡組件。站在應用視角,本次 WWDC 網絡類 session 可分爲兩大類:

  • 無線網絡體驗優化實踐在系統層面的標準化;
  • 本地網絡應用的權限管控增強。
    在第一類議題中,我們看到很多已經在手淘中的類似實踐,或標準或自研,說明手淘在網絡技術的開發與應用上還是較爲深入和前沿的,基本走在全球業界前列。根據我們手淘的業務特點,筆者重點關注第一類 session,並簡單探討該新技術可以我們帶來什麼樣啓發和變化。

使用加密 DNS

DNS 解析是網絡的連接的第一步,這裏提到的"加密 DNS"是什麼、它解決什麼問題?

解決什麼問題

一是傳統 Local DNS 的查詢與回覆均基於非加密 UDP,我們常見的 DNS 劫持問題

二是 Local DNS Server 本身不可信,或者本地 Local DNS 服務不可用。

其實針對 DNS 解析過程中以上兩個問題,在實踐中早就有了解決方案,就是 HTTPDNS, 各大雲廠商也都有成熟產品售賣,那蘋果這裏的加密 DNS 與我們的現有 HTTPDNS 有何不同呢?

現有 HTTPDNS 有兩個很大的問題:

  • 一是對業務的侵入性,即如果某個網絡連接需要使用 HTTPDNS 的能力,首先他需要集成服務商提供的 SDK, 引入相應的 Class,然後修改網絡連接的階段的代碼;
  • 二是面臨各種技術坑,比如 302 場景的 IP 直連處理、WebView 下 IP 直連如何處理 Cookie、以及 iOS 上的老大難的 SNI 問題等,這些都需要業務開發者付出極大的努力和嘗試。

iOS 14 上的 Encrypted DNS 功能很好的解決了現有 HTTPDNS 的存在的問題。

規範與標準

iOS 14 開始系統原生支持兩種標準規範的 Encrypted DNS, 分別是 DNS over TLS 與 DNS over HTTPS.

具體協議標準可以參見:rfc7858 (DoT) 、rfc8484 (DoH)

如何實現

iOS 14 提供了兩種設置加密 DNS 的方法。第一種方式是選擇一個 DNS 服務器作爲系統全局所有 App 默認的 DNS 解析器,如果你提供的是一個公共 DNS 服務器,你可以使用 NEDNSSettingsManager API 編寫一個 NetworkExtension App 完成系統全局加密 DNS 設置。或者如果你使用 MDM(Mobile Device Management) 管理設備的企業設置;你可以推送一個包含 DNSSettings paload 的 profile 文件完成加密 DNS 設置。

使用 NetworkExtension 設置系統域全局 DNS 服務器示例代碼:

上述代碼首先通過 NEDNSSettingsManager 加載配置,加載成功後,創建一個基於 DoH 協議的 NEDNSOverHTTPSSettings 實例,對其配置 DNS IP 地址和域名,DNS IP 地址是可選配置的。然後將 NEDNSOverHTTPSSettings 實例配置到 NEDNSSettingsManager 共享實例的 dnsSettings 屬性,最後保存配置。

一條 DNS 配置包括 DNS 服務器地址、DoT/DoH 協議、一組網絡規則。網絡規則確保 DNS 設置兼容不同的網絡。因爲公共 DNS 服務器是無法解析本地網絡的私有域名,比如只有企業 WiFi 網絡內的 DNS 服務器可以解析員工訪問的私有域名,這類情況就需要手動指定網絡規則兼容企業 WiFi 網。

網絡規則可以針對不同網絡類型定義行爲,比如蜂窩網、WiFi、或者具體的 WiFi SSID。在匹配的網絡下,你可以禁用配置的全局 DNS 設置,或者對私有域名不使用 DNS 設置。

而在一些情況下,兼容性會自動處理。比如強制門戶網絡 (captive portal), 手機在連接上某個 WiFi 的時候,自動彈出一個頁面輸入賬號密碼才能連接網絡。這種情況下系統域全局 DNS 配置會做例外處理。相類似的,對於 VPN 網絡,在 VPN 隧道內的解析將使用 VPN 的 DNS 設置,而不使用系統域 DNS 配置。

網絡規則設置示例代碼:

上述代碼設置了三個網絡規則,第一個規則表示 DNS 配置應該在 SSID="MyWorkWiFi"的 WiFi 網絡生效,但對私有企業域名 enterprise.example.net 不開啓。第二個規則表示規則在蜂窩網下應該被禁止使用 ; 第三個 NEOnDemandRuleConnect 表示 DNS 配置應該默認開啓 ; 因爲配置 DNS 是系統支持的,所以在編寫 NetworkExtension App 時不需要實現 Extension 程序,只需要在 Network Extensions 中勾選 DNS Settings 選項。

運行 NetworkExtension App,DNS 配置將會被安裝到系統,爲了讓 DNS 配置生效,需要前往設置 -> 通用 ->VPN & Network->DNS 手動啓用。

一些網絡可能會通過策略阻止你使用加密的 DNS 服務器。這些網絡嘗試分析 DNS 查詢請求來過濾流量。對於此類網絡,系統會被標記隱私警告提示,在該網絡下的網絡連接將會失敗。

第二種方式是針對單個 App 的所有連接或部分連接啓用加密 DNS。

如果你只想爲你的 App 使用加密 DNS,而非涉及整個系統域。你可以適配 Network framework 的 PrivacyContext,對你的整個 App 開啓加密 DNS,或者僅對某一連接開啓。不管使用的是 URLSessionTask,或 Network framework 連接或 getaddrinfo 的 POSIX API,這種方式都有效。

對單個連接使用加密 DNS 示例代碼:

驗證請求是否使用加密 DNS:

如果你想在 App 範圍內使用加密 DNS,你可以配置默認的 PrivacyContext;App 內發起的每個 DNS 解析都會使用這個配置。不管是 URLSessionTask,還是類似 getaddrinfo 的底層 API。

現有實踐對比及啓發

  • 與現有實踐對比

    上文已經提到過 HTTPDNS 產品,手淘的域名解析,採用的是類似於 HTTPDNS 原理,但更加複雜的調度方案。但是相比於這種系統層面的標準化方案,解決了現有實踐中的兩大難題:

    • 對業務的侵入性:業務必須修改現有網絡連接的階段的代碼;
    • 交互的標準兼容性不足:IP 直連下的 302 問題、Cookie 問題、SNI 問題等
  • 帶來的變化

    一是在應用內部,我們可以對業務透明提供提供全局的域名調度或者域名兜底解析能力, 不再是隻有用到特定組件或 SDK 纔可以。二是蘋果放開系統級別 DNS 接管後,用戶設備上的服務相比原 Local DNS 的“中立性”如何管控?對特定業務是否甚至會造成惡化?如果對外部應用的這種“中立性”疑問或擔心確實存在,則這種系統標準化的加密 DNS 對手淘這種大型應用則是必選項。

受限網絡中推送

解決什麼問題

當向 iOS 設備推送消息時,業務服務器需要將消息先發送給 APNS 服務器,APNS 服務器再將消息轉換爲通知 payload 推送給目標設備。如果設備所在的 WiFi 網絡沒有連接互聯網或者當前網絡受限,比如在遊艇、醫院、野營地這些地方,設備沒有與 APNS 服務器建立有效連接,APNS 消息投遞將會失敗。

對於一些 App 來說,接收推送消息是 App 的一項非常重要的功能,即使在沒有互聯網連接的情況下也需要持續穩定工作。爲了滿足這一需求,iOS 14 中增加了本地推送連接 (Local Push Connectivity)API,這是 NetworkExtension 家族中新的 API。本地推送連接 API 允許開發者創建自己的推送連接服務,通過開發一個 App Extension,在指定的 WiFi 網絡下可以直接與本地業務服務器通信。

上圖中,App Extension 主要負責保持與本地業務服務器之間的連接,以及接收業務服務器發來的通知。因爲沒有了 APNS,開發者需要爲業務服務器與 App Extension 定義自己的通信協議。主 App 需要配置具體在哪個 WiFi 網絡下使用本地推送連接。當 App 加入到指定的 WiFi 網絡,系統會拉起 App Extension, 並在後臺持續運行。當 App 斷開與指定 WiFi 網絡的連接,系統將停止 App Extension 運行。

如何實現

本地推送連接對那些推送功能非常重要,而設備所在網絡受限的場景非常適合。而對於常規的推送需求,依然推薦使用 PushKit 或 UserNotification API 處理 APNS 推送消息。每臺設備和 APNS 服務器之間只建立一條 APNS 連接,設備上所有 App 都公用這一條連接,所以 APNS 非常省電。

APNS 與本地推送連接對比:

新的本地推送連接 API 由兩個類組成:NEAppPushManager 和 NEAppPushProvider。NEAppPushManager 在主 App 中使用,主 App 使用 NEAppPushManager 創建一個配置,配置中指定具體哪個 WiFi 網絡下運行本地推送連接。你可以使用 NEAppPushManager 加載 / 移除 / 保存配置。NEAppPushProvider 則在 App Extension 使用。在 App Extension 中實現一個 NEAppPushProvider 的子類,子類中需要覆蓋生命週期管理方法,這些方法在 App Extension 運行和停止時被調用。

App Extension 主要處理兩類推送,一類是常規的推送通知,一類是 VoIP 呼叫通知。如果是常規的推送通知,App Extension 收到消息後,可以使用 UserNotification API 構造一個本地推送顯示推送信息。如果是 VoIP 呼叫通知,App Extension 使用 NEAppPushProvider 類將呼叫信息報告給系統。如果此時主 App 不在運行,系統將喚醒主 App,並將消息投遞給它,最後主 App 再使用 CallKit API 顯示呼叫界面。

下面是在主 App 中使用 NEAppPushManager 的示例代碼:

上述代碼創建了一個 NEAppPushManager 實例,並配置實例的各個屬性值。matchSSIDs 表示在指定的 WiFi 網絡下才啓用本地推送連接。providerBundleIdentifier 表示 App Extension 的包名,providerConfiguration 是傳給 App Extension 的一些配置,在 App Extension 內可以通過 NEAppPushProvider 的 providerConfiguration 屬性獲取。isEnabled 表示使用這個配置開啓本地推送連接。最後調用 saveToPreferences 方法持久化配置。下面是 App Extension 實現 NEAppPushProvider 子類的示例代碼:

系統調用 start(completionHandler:) 方法啓動 App Extension,在這個方法內 App Extension 與本地業務服務器建立連接。當 App Extension 停止運行,系統調用 stop(with:) 方法, 在這個方法內 App Extension 斷開與業務服務器的連接。handleIncomingVoIPCall(callInfo:) 方法在收到 VoIP 呼叫時被調用,在方法內 App Extension 調用 reportIncomingCall(userInfo:) 將該事件上報給系統。隨後系統將會喚醒主 App,並將呼叫信息傳遞給主 App。主 App 處理系統傳入的呼叫信息示例代碼:

以上代碼在 AppDelegate 的 didFinishLaunchingWithOptions 方法內使用 NEAppPushManager 加載所有配置,並設置每個 NEAppPushManager 示例的代理屬性。系統會在主線程中將接收到呼叫信息通過 didReceiveIncomingCallWithUserInfo 方法投遞給主 App。主 App 必須通過 CallKit API 將呼入信息上報給 CallKit 展示呼叫界面。

價值場景

如果只考慮推送本身,對於手淘或者大部分消費類應用來說,筆者認爲價值並不大,因爲此類 APP 不可能在一個封閉的本地網絡裏去部署資源來提供服務能力。這裏一個可應用的點在於:設備一旦進入特定網絡環境,觸發 App Extension, 進而喚起主 App,應用可在後臺完成一定事務。因爲 iOS App 一直缺乏後臺服務能力,這種特定網絡環境的觸發喚醒,極大的補充了這一能力。

現代網絡技術的應用

蘋果在這次 WWDC 中,把一些較新的網絡技術,對應用的體驗提升,做了一個簡單綜述,包括 IPv6、HTTP/2、TLS1.3, MTCP、以及 HTTP/3。這些技術在手淘基本都有涉及,有些是已經是大規模部署、有些是正在逐步推進中。對各個應用來說,如果已經在應用這些技術了,則雲端均儘可能標準化,便於進一步推廣和複用。這裏簡單的對蘋果的綜述做一個搬運:

IPv6

蘋果根據最新統計,蘋果全球設備 TCP 連接佔比中,IPv6 佔比 26%,IPv4 佔比 74%,其中 74% 的佔比中有 20% 是因爲服務端沒有開啓 IPv6 支持。在建連時間方面,由於減少了 NAT 使用,提高了路由效率,IPv6 的建連時間比 IPv4 快 1.4 倍。開發者只需使用 URLSession 和 Network.framework API,IPv6 網絡適配將自動支持。

以上是蘋果的數據。阿里巴巴集團從 18 年開始大力推進 IPv6 的建設,目前我們在 IPv6 整體應用規模上在業界是屬於頭部大廠。但根據我們應用的實際效果數據,以及業界友商的應用數據,性能提升並不明顯。以及工信部的 IPv6 建設目標來看,性能提升也不是 IPv6 建設的目標,只要達到 IPv4 同等水平即可。IPv6 的意義就在解決 IPv4 地址空間枯竭的問題,更多的在規模、安全,而不是性能提升。就企業而言,例如可以降低 IPv4 地址的購買費用;就國家而言,IPv6 突破了 IPv4 中國境內無 DNS 根結點的風險。IPv6 目前階段在國內尚處於發展中,基礎運營商覆蓋、家用網絡接入設備支持、應用服務的支持,正在快速發展中。

HTTP/2

HTTP/2 的多路複用特性使得對同一服務器的多個請求複用到單個連接上,不必等待前一個請求響應結束才能發送下一個請求,不僅節省了時間也提升了性能。頭部壓縮特性提升了帶寬利用率,通過簡化消息內容,從而降低消息的大小。根據最新統計,在 Safari 中 HTTP2 Web 流量佔比 79%,HTTP/2 比 HTTP/1.1 快 1.8 倍。如果服務端支持 HTTP/2,URLSession 將默認使用 HTTP/2。

在手淘業務中,全面應用 HTTP2 已經有三四年之久,其使用規模比蘋果統計的結果要高的多,取得了巨大的體驗提升收穫。手淘的核心流量分爲兩類:API 請求 MTOP 於圖片 CDN 請求,這兩類的 HTTP2 的流量佔比約超過 98%,基本實現核心流量全部長連化。但當前手淘的 HTTP2 技術在設備支持之前即大規模應用,協議棧完全自研,爲進一步提升建聯速度,又做了一些預置證書的優化。下一步將逐步使基礎網絡依賴標準化平臺能力,降低對私有協議棧的依賴,可降低包大小以及提升產品複用體驗。

TLS1.3

TLS1.3 通過減少一次握手減少了建連時間,通過形式化驗證 (Formal Verification) 與減少被錯誤配置的可能性,提高了通信安全。從 iOS 13.4 開始,TLS1.3 默認在 URLSession 和 Network.framework 開啓。根據最新統計,在最新的 iOS 系統上,大約 49% 的連接使用 TLS1.3。使用 TLS1.3 比使用 TLS1.2 建連時間快 1.3 倍。如果服務端支持 TLS1.3,URLSession 將默認使用 TLS1.3。

目前手淘的 HTTP/2 的 TLS version 仍然還是基於 TLS1.2,不過爲了解決低版本 TLS 的性能之殤,手淘網絡通過預置證書與自定義 SSL 握手流程,創新自研了 slight-ssl 協議,實現了 0rtt 的效果。TLS 1.3 標準在系統層面的全面支持,對應用來說是一個明確的技術趨勢信號,我們的網絡協議需儘快標準化,對網絡管道兩端來說,客戶端應用層網絡接口需全面升級到 NSURLSession 或 Network.framework, 實現對系統標準能力的應用;雲端也許全面支持 TLS1.3,可不依賴端側 SDK 即可提供更新安全、高效、標準的網連接。

MultiPath TCP

MultiPath TCP 允許在一條 TCP 鏈路中建立多個子通道。當設備切換網絡時,單個 TCP 連接依然可以繼續使用。蘋果的 Apple Music 與 Siri 服務都使用了 MultiPath TCP。Apple Music 在使用 MultiPath TCP 之後, 音樂播放卡頓次數減少了 13%, 卡頓持續時間減少了 22%。開啓 MultiPath TCP 需要客戶端和服務端都支持才能生效,服務端支持 MultiPath TCP 可參考: http://multipath-tcp.org/

其實手淘在這方面也有類似的優化嘗試:多網卡:同時通過 Wi-Fi 與蜂窩網連接目標服務器,提升數據傳輸速度。其技術原理與 MTCP 不一樣,但也是想在上層起到類似作用:通過多路連接,提升數據交換帶寬。業界也有類似的產品,例如華爲的 LinkTurbo。

HTTP/3

HTTP/3 是下一代 HTTP 協議,它是構建在新的 QUIC 傳輸協議之上,QUIC 協議內建了對 TLS1.3 的支持,並提供了與 HTTP/2 一樣的多路複用功能,並進一步減少了隊頭阻塞的發生,讓單個請求或相應的丟失不影響到其他請求。使用 QUIC 的 HTTP/3 還具有較高的保真度信息,以提供改進的擁塞控制和丟包恢復。同時也包括內建的移動性支持,這樣網絡切換不會導致正在進行的操作失敗,可以無縫在不同網絡之間切換。不過 HTTP/3 目前還處於草案階段,iOS 14 和 MacOS Big Sur 包括了一個對使用 URLSession 的 HTTP/3 的實驗預覽支持,這個功能可以在開發者設置中開啓。同時 Safari 的 HTTP/3 支持也可在開發者設置中開啓。

在手淘中,我們的 QUIC 應用應該會早於蘋果系統先行支持,目前已經在灰度中。

本文轉載自公衆號淘系技術(ID:AlibabaMTT)。

原文鏈接:

https://mp.weixin.qq.com/s?__biz=MzAxNDEwNjk5OQ==&mid=2650409248&idx=1&sn=0cd4e62fbf1807c698f163279f2b5c79&chksm=8396c138b4e1482e912016b0b7fc8e63da547bc3278a990dcc879a7fd6e1d5aca4ecb2c5f92c&scene=27#wechat_redirect

相關文章