DNS域名解析就是將我們熟知的域名轉換為ip的服務。如將 www.baidu.com 轉換為 61.135.169.125 這樣的ip地址。
想要記住域名比較容易,但是想要記住ip就不容易了,由此可見dns服務是多么的重要。
解析流程
如上圖所示就是一個最簡單的查詢流程,根服務器是不會給任何人提供遞歸查詢服務的,它只提供 迭代查詢,根只是知名一個方向,讓你去找相關的頂級域服務器。
但是站在客戶端的角度,這就是一次 遞歸查詢 過程。本地DNS就是做這個的,本地dns服務器一般是通過DHCP服務器配置,本地DNS由你所在的網絡服務商ISP,如電信,移動等自動分配配置的,它通常就是在你的網絡服務商的某個機房中。
負載均衡
dns不僅僅可以對域名解析出ip。它還能根據客戶端的所在地理位置解析出對客戶端最優質的ip。這個怎么理解呢,比如我在深圳訪問 baidu.com ,那么dns服務器會將解析成就近的機房的ip地址,而不會讓我去訪問位于北京的機房。
這就是 全局負載均衡(GSLB,Global Server Load Balance)。因為,為了保證服務應用的高可用性,往往會部署多個機房,每個地方都會有自己的IP地址。當用戶訪問某個域名的時候,這些IP地址可以輪詢這些機房。另外盡可能希望,北京的用戶訪問北京的機房,上海的用戶訪問上海的機房。這樣客戶體驗就會非常好,訪問速度也會非常快。
有什么問題木有呢?
看似十分完美的 GSLB 和 SLB。實則有很多的問題。
- 問題一 本地緩存
不是每一個請求都是去訪問的權威DNS服務器,而是訪問過一次,就把結果緩存到本地,當其他人來訪問的時候,直接就返回了這個結果。
一些運營商會把一些靜態頁面,緩存到本地運營商的服務器中,這樣用戶請求的時候,就不用跨運營商進行訪問了,這樣既加快了速度,也減少了運營商之間的流量計算的成本。
再就是本地緩存,往往使得全局負載均衡失敗。因為上次進行緩存的時候,緩存的地址不一定是這次訪問離客戶最近的地方,如果把緩存的數據返回給客戶,那就繞遠了。 - 問題二 域名轉發問題
有一些本地DNS服務器比較黑心,收到解析請求之后,直接轉發給了其他運營商去做解析,自己只是外包出去了。比如你是移動用戶,你發起對baidu.com 的解析請求,而移動的本地DNS服務器將解析轉給聯通的DNS服務器,最終GSLB誤認為你是聯通的,返回一個相對于聯通用戶的更優解。結果每次客戶端訪問其實都是跨運營商的,速度就會慢很多。 - 問題三 出口NAT
在 IPV4 地址不夠用的大環境下,其實有十分多的NAT,也就是網絡地址轉換。使得從這個網關出去的包都換成了一個新的IP地址。一旦做了地址轉換,可能GSLB就不知道你的運營商,源IP了。 - 問題四 域名更新
受TTL限制,解析變更在全網的生效時間較長。我們這里一個機房掛了,將這個機房的A記錄摘掉。但是往往過了一天還能發現有流量過來(這就和TTL沒關系了,還是本地DNS層層緩存惹的禍) - 問題五 解析延遲問題
一個解析需要遞歸本地DNS 可能多次,再去迭代。比較慢。
既然傳統 DNS 問題這么多,那怎么解決呢?
有,那就是HTTPDNS
HTTPDNS 的工作模式
HTTPDNS不走傳統的DNS解析,而是自己搭建基于HTTP協議的DNS服務器集群,分布多個地點和多地運營商,當客戶端需要DNS解析的時候,就通過HTTP協議進行請求這個服務器集群。到就近的地址。
而使用HTTPDNS的往往是手機應用,需要在手機端嵌入支持HTTPDNS的客戶端SDK。
在客戶端的SDK里動態請求服務端,獲取HTTPDNS的服務器列表。緩存到本地,隨著不斷域名解析,SDK也會在本地緩存DNS域名解析的結果。
當應用要訪問一個地址時,先看下是否有緩存(這個緩存時手機應用自己做的,不走運營商的緩存,所以如何更新,合適更新全在自己的掌控之中)如果本地沒有緩存,那就請求 HTTPDNS的服務器吧。而手機客戶端當然知道收集在哪個運營商,在哪個地址,由于是直接的HTTP通信,HTTPDNS也能更好的返回結果信息,更好的做到全局負載均衡。
curl 'https://dns.google.com/resolve?name=www.qq.com&type=A&dnssec=true&ecs=112.12.1.1' -s |jq
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": false,
"CD": false,
"Question": [
{
"name": "www.qq.com.",
"type": 1
}
],
"Answer": [
{
"name": "www.qq.com.",
"type": 5,
"TTL": 203,
"data": "news.qq.com.edgekey.net."
},
{
"name": "news.qq.com.edgekey.net.",
"type": 5,
"TTL": 21109,
"data": "e6156.dscf.akamaiedge.net."
},
{
"name": "e6156.dscf.akamaiedge.net.",
"type": 1,
"TTL": 17,
"data": "23.198.121.20"
}
]
}
HTTPDNS的調度設計
在客戶端,可以知道確切的地理位置信息,運營商。HTTPDNS可以根據這些信息返回最佳的服務節點。
如果有多個節點,還會考慮錯誤率,請求時間,服務器壓力,網絡狀況等,進行綜合選擇。而非僅僅考慮地理位置。當有一個節點宕機或者性能下降時,盡快切換。
在服務端,服務端可以配置不同的服務質量的權重,優先級,對客戶端上報的錯誤率,請求時間,請求質量等數據,統計,分析,聚合,以此查看不同的IP的服務質量。
為了不讓調度失真,客戶端可以根據,不同的移動網絡運營商的WIFI的SSID分維度緩存,不同的運營商或者WIFI解析出來的結果會不同。
GOOGLE HTTPDNS
2016.4.1日,Google正式啟用了 DNS-Over-HTTPS 域名安全查詢服務
該服務支持以下參數:
- name
唯一的一個必選string參數,就是你要查詢的域名地址。長度在1-255,字符在[0-9a-zA-Z-.],不支持非ASCII字符。 - type
可選string, 默認是1。RR type可以用[1, 65535]之間的數字表示,或者canonical string表示(A, AAAA等)。目前支持:A, AAAA,CNAME, MX,ANY,PTR - cd
布爾型,默認是false。CD(Checking Disabled)字段,設置為true時禁用DNSSEC validation。可用格式:cd, cd=0, cd=1, cd=false, cd=true - edns_client_subnet
可選string,默認為空。這個是edns0-client-subnet選項。格式是:IP/Mask。比如:1.2.3.4/24,2001:700:300::/48。
edns_client_subnet 這里有個坑,比如你有海外需求,需要將 域名cname到海外著名的cdn廠商,比如fastly,akamai等,你需要確定cdn廠商認不認edns擴展,比如 akamai 的權威是不認 阿里httpdns ,騰訊httpdns 的edns 擴展的,也就是你用 ali,tencent 的httpdns 解析akamai 的是會調度錯誤的。
怎么測試權威是否支持我們的edns 擴展呢?
以 www.qq.com 為例
找到域名的權威。
$ dig www.qq.com +trace @114.114.114.114
...
www.qq.com. 86400 IN NS ns-cmn1.qq.com.
www.qq.com. 86400 IN NS ns-tel1.qq.com.
www.qq.com. 86400 IN NS ns-cnc1.qq.com.
www.qq.com. 86400 IN NS ns-os1.qq.com.
www.qq.com. 300 IN CNAME public-v6.sparta.mig.tencent-cloud.net.
...
對權威發起 subnet 查詢, www.qq.com 被 cname 到 騰訊云上去了,看來權威在騰訊云上
dig public-v6.sparta.mig.tencent-cloud.net. @ns1.qq.com. +subnet=12.13.1.12
看看是否有解析結果。
參考 1. 劉超老師的極客時間
2.https://blog.csdn.net/windyf2013/article/details/79727348