banner
jzman

jzman

Coding、思考、自觉。
github

IPV6、IPV4雙堆疊問題

PS:人生和代码一样,不反思、不迭代就無法獲得成長。

最近接觸到單雙棧問題,簡單梳理下,雙棧與單棧,也就是 IPV4 相比,雙棧客戶端的應用程式會遇到明顯的連接延遲,使得雙棧客戶端的使用者體驗變差,下面了解一下雙棧問題以及其解決方法,主要內容如下:

  1. 雙棧選擇問題
  2. IPV6 無法訪問時的延遲
  3. Happy Eyeballs
  4. 實際運用

雙棧選擇問題#

雙棧選擇問題及 IPV6/IPV4 選擇問題,首見於 RFC1671 文件,IPV6 (Internet Protocol version 6) 就是網際網路協議第六版,IPV4 (Internet Protocol version 4) 就是網際網路協議第四版,IPV6 主要解決的問題是 IPV4 的地址資源日益枯竭,IPv6 增強的關鍵是將 IP 地址空間從 32 位擴展到 128 位,從根本上實現不受限制的唯一 IP 地址,雙棧選擇問題是在網際網路迅速發展的大背景下出現,當處於雙棧狀態下,DNS 解析出來的地址有兩類地址,,單棧狀態下,DNS 解析出來是 IPV4 或 IPV6 地址,當然目前說到單棧一般都是默認單棧 IPV4。

IPV6 無法訪問時的延遲#

當 IPV6 不能訪問時,支持 IPV6 的程式需要延遲幾秒鐘才能正常切換到 IPV4,這會影響使用者體驗,為了不影響使用者體驗有些系統會直接禁用 IPV6。

IPV6 不能訪問的原因如下:

Reasons for such failure include no connection to the IPv6 Internet, broken 6to4 or Teredo tunnels, and broken IPv6 peering.

下面看下 IPV6 連接失敗的流程圖:

image

如上圖所示,客戶端域名解析獲取到 IPV6、IPV4 地址,然後先請求 IPV6 未連接成功,幾秒後切換到 IPV4 連接成功,其中 IPV6 等待連接到連接失敗的這段時間就是 IPV6 無法訪問時的耗時。

Happy Eyeballs#

RFC6555 中定義了一種減少可見延遲的演算法要求 Happy Eyeballs,其最基礎的兩個目標如下:

  1. 為使用者提供快速連接 IPV6 和 IPV4 的能力,即快速嘗試使用 IPV6 進行連接,如果快速連接未成功,則切換到 IPV4 進行連接。
  2. 避免同時連接 IPV6 和 IPV4 而對網路造成衝擊。

下面是上述思想的示意圖如下:

image

如上圖所示,客戶端同時通過 IPV6 和 IPV4 發送兩個 TCP SYN 包,IPV6 未連接成功,IPV4 則響應成功,重試 IPV6 直到使用者放棄連接 IPV6 直接切換到 IPV4 即可。

執行完上述過程後,客戶端則知道 IPV6 和 IPV4 地址是否連接成功,客戶端可以把結果緩存起來,避免後續的連接嘗試中影響網路,如在上面示例中 IPV6 連接是失敗,後續連接中可以直接切換到 IPV4 進行連接,可以為緩存連接結果設定一個有效期,如 10 分鐘,之後可刷新連接狀態,這就是在一定程度上減少了 IPV6 連接異常時的耗時,有助於增加使用者體驗。

下面是一個 IPV6 工作正常的示意圖:

image

如上圖所示,客戶端同時通過 IPV6 和 IPV4 發送兩個 TCP SYN 包,IPV6 和 IPV4 都連接成功,IPV6 直接連接成功,則直接走 IPV6,忽略 IPV4 即可,同樣記錄 IPV6 連接狀態,可在設定的有效期內直接 IPV6 進行連接,

只要客戶端主機是支持雙棧的,Happy Eyeballs 機制就會一直存在,只要存在僅支持 IPV4 的伺服器存在,Happy Eyeballs 就會一直存在,隨著時間的推移,IPV4 將會逐漸退出歷史舞台,Happy Eyeballs 的實現場景可能不同,但是基本遵循上述要求。

實際運用#

一般應用層使用到的域名解析 API 如下:

public static InetAddress[] getAllByName(String host)

上述方法會返回域名 host 對應的 IP 地址,此時就可以根據 IP 地址是 IPV6 地址還是 IPV4 地址進行單雙棧問題的適配了,具體實現可以根據需求進行調整和完善,上面介紹的 Happy Eyeballs 主要就是在解決雙棧時帶來的延遲問題,大型 App 應該都有自己的對應演算法實現,有的甚至 DNS 這塊也是自己實現的,這裡了解一下。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。