最近遇到一個小問題,在某些用戶的請求中會莫名其妙的出現重定向而後致使404,在這裏分享下致使這種問題的緣由。
這裏不會介紹DNS和CDN,若是想了解請google或百度,有好幾斤的數據能夠看,我也不必再說了。這篇文章主要是從關於客戶端DNS解析和CDN服務解析的整個流程
角度去解釋我遇到的這個很幼稚的bug
。linux
DNS對於大多數同窗來講均可能知道是幹嗎的,可是深刻了解工做原理可能有些模糊,首先它它分佈在不少個階段,總體分爲兩大塊:本地DNS服務,遠端DNS服務。程序員
每臺電腦本地都會配置一個DNS解析文件,在Nginx上咱們能夠在 /etc/resolv.conf 中查看,固然也能夠從界面中查看。數據庫
下面是我在CLI查看個人本地DNS服務配置,即DNS客戶機配置(/etc/resolv.conf)瀏覽器
下面是我在設置中查看DNS服務配置緩存
你們會問,這兩個同樣嗎?只不過一個是在文件系統查看一個是在GUI上查看,二者沒區別吧?嗯,是的沒區別。服務器
實際上,修改本地的DNS解析規則,在Nginx上有三個地方,分別是網絡
hosts文件-->網卡配置文件-->DNS服務器地址配置文件
咱們剛纔修改的只是系統的DNS服務器地址配置文件,固然GUI上也是對應的這個文件。前兩個配置方式比較粗暴,在這裏就不講了,有傷大雅。app
分析一下配置文件中的字段(實際上還有不少,先說兩個吧):dom
本地的DNS服務器列表
,它的格式是IP地址,v4 v6 d均可以,遠端或本地地址均可以,甚至這個地址能夠填寫一個本地的服務,而後咱們就能夠自定義處理DNS解析服務了。nameserver
這個字段就太好玩了,一般家庭版的地址是192.168.0.1
,也就是大多數路由器的IP地址,而後用戶能夠在本身的路由器設置頁面配置DNS解析服務器的地址。belowsocket
固然,你也能夠不使用路由器來轉發你的DNS解析,直接填寫這個根DNS服務器
地址,也就是圖上面的222.*。
做爲程序員,突發奇想,咱們還能夠玩的更浪一些~~~,就好比:
添加一個本地域名解析服務,也就是添加一個127.0.0.1在你的DNS配置文件中,注意必定要添加在第一行,別忘了nameserver是in order的哦。
而後在本地開一個UDP
服務,監聽53端口(爲何是UDP爲何是53端口,好奇同窗請trace here),你就會看到本地的DNS處理記錄:
let dgram = require('dgram'); let socket = dgram.createSocket('udp4'); // 服務端監聽一個端口 數據到來時 能夠讀出信息 socket.bind(53,'localhost',function(){ //讀取消息 socket.on('message',function(data,rinfo){ console.log(data.toString()); }) });
下面這些亂七八糟的,就是DNS解析記錄...
咱們能夠修改上面的代碼來自定義解析後的信息
,我不知道這個返回狀態應該怎麼設定,沒事閒的同窗能夠去查查怎麼能夠僞造這個信息,聽起來很刺激... 不過我以爲不太可能,53端口受特殊保護,就連監聽和查看它的佔用狀況都須要提權
,上述代碼linux上出EACCES
錯的能夠加上sudo,win提權太麻煩不說了。
說了 一大堆沒用的,回正題,如今開始咱們假設本地DNS服務接受了一個軟件的解析請求~~
咱們假設上述的 hosts文件-->網卡配置文件-->DNS服務器地址配置文件,前兩個不作任何處理的狀況下。如下順序處理。
本地DNS服務的任務就是接受計算機軟件的DNS解析服務,去向根DNS服務器發送請求,得到最終的IP地址。
若是本地有 DNS resolver 的話,也是能夠緩存你的DNS解析的,什麼是Resover?就是我們剛纔創建在53端口的服務,它就是一個Resolver。
// 驗證是否存在 resolver sduo lsof -i:53 // or 查看 /etc/resolv.conf
resolver 有可能緩存上一次DNS解析結果。若是碰到惡意的resolver,看誰不順眼就能夠篩選全部某站的主域名(好比競爭對手的...嘿嘿)返回一個不存在的ip地址,而後這個域名在那臺電腦上就over了,除非技術手動撤銷這個resolver,不然卸載重裝,重啓,通通很差使。
因此,友情提醒:儘可能不要使用本地的DNS resolver。
,
接着從上面的本地DNS服務開始說,它把解析請求發送給 20.20.* 服務器,這個服務器就是根DNS,全部DNS解析請求都通過它來轉發
,
根DNS服務器免費的沒有幾個,國內的114.114*比較快一點,國外的Google的4個8或者4個1,都是廣泛使用的。那麼又一個問題,世界上這麼多電腦才這麼幾個服務器,並且每臺電腦的DNS解析請求是很是頻繁的,這幾個服務器受得住嗎?
首先,它確實是接受全部的請求的,但它不負責處理這個解析,只負責分類並返回子DNS服務器IP
。而後LocalDNS接收到這個子DNS服務器IP後,再去向子DNS迭代
查詢。
這個階段,若是你本地有DNS緩存服務的話,它會記住某個域名與它所屬的子DNS的IP地址,下次請求直接去子DNS地址,而不用通過ROOT DNS處理。
子DNS分不少區,這個分類其實就是根據域名的後綴來的,好比,有 COM DNS 服務器,它只負責 com這個後綴的域名解析。固然還有其餘類型的,好比 .cn .net。固然,不可能每一個後綴都來一臺服務器,流量較少的的後綴應該被分在一個區裏。
子DNS接到LocalDNS請求以後,查詢此域名以後發現它已經交給專屬DNS服務器(也就是你購買域名時設置的域名解析服務器)處理
子DNS的做用就是幫助RootDNS減小不少查庫和處理請求的時間。
服務器DNS屬於咱們域名下的專屬DNS服務器,咱們可使用本身的DNS服務器配置到你的域名上(申請DNS服務器須要到國內註冊局申請辦理
)。
若是是本地內網搭建,就沒那麼多規則,可使用Bind ((Berkeley Internet Name Domain))。
一般,咱們在阿里雲購買的域名綁定上域名解析就能夠了,默認使用的是萬網的DNS服務器,若是你有本身的DNS服務器的話,能夠在域名管理中配置。
最後來張圖通一通。以我司客戶端爲例:
LocalDNS
接收到一個客戶端發送的域名解析請求,看看本地有沒有上次緩存的現成的hetao101域下的DNS服務器
。若是沒有,取出第一個nameserver(也就是根DNS服務器),進行迭代查詢
。若是有,直接跳到第5步。根DNS
解析咱們的www.hetao101.com地址屬於 com 區,而後把 com 區的子DNS服務器的IP返回給LocalDNS
處理。LocalDNS
收到子DNS
的IP,而後再次發送迭代查詢向子DNS子DNS
查詢數據庫,找到www.hetao101.com這個域名對應的服務器DNS
地址,而後把地址返回給LocalDNS
。注意,以上的遞歸查詢和迭代查詢的區別,遞歸查詢的是:我向A請求,A你必須得給我一個結果,不到黃河不死心。而迭代查詢是,我向A請求,A有可能沒有這個東西,它把B返回給你,讓你和B問...
網絡就是數個燈泡中間的導線,電線長了,電流抵達的速度也就慢了,燈泡亮的速度就慢了。。。
因此,咱們在導線的中間加上了一個繼電器式
的資源服務器。也就是CDN服務器。保證資源快速響應給局部用戶。
CDN服務器一般包括一個源站和子節點(其餘區域的資源服務器),上傳文件到CDN服務器首先到達源站,而後源站分發給子節點。而後當客戶端請求時候經過它們本身的DNS服務器解析請求IP(地理位置因素),而後返回不一樣的子節點地址。
若是源站的資源被替換或者刪除,子節點也會與它同步。
簡單的打了個比方,具體使用場景及原理,能夠自行Goog,很少說了廢話了,下面簡單說下我遇到那個問題。
最近遇到一個小問題,在更新資源文件後,在某些用戶的請求中會莫名其妙的出現
302
而後重定向地址是404,在這裏分享下致使這種問題的緣由。
上下文:這個請求是阿里雲OSS的,客戶是河北滄州移動運營商,重定向後的IP地址後面添加相比源路徑多了不少層路徑,位置是河北石家莊的移動網絡。
我一開始的分析是,本地DNS服務或運營商緩存了DNS解析(阿里雲DNS解析後的IP是能夠根據客戶端的區域分配就近節點的,因此應該被分到了石家莊節點),而後當我更新這個文件時,因爲ISP緩存沒有到期(假定是ISP,還有多是本地DNS Resolver),而後更新文件後,繼續請求上次的解析後的地址(地址上是有文件的hash的),致使資源404(hash值被更新)。
仔細想一下是不對的,首先DNS解析只會返回域名區段,不會給你添加路徑。第二若是是阿里雲子節點在上傳文件到源站的時候,就會同步到各個子節點,因此不會出現404的狀況。
那麼,若是這個重定向的IP地址不是阿里雲的,難道是運營商本身的,它把響應文件緩存起來,而後放到本身的緩存服務器,若是請求在緩存期內就從運營商本身的緩存服務器裏取?我估計這個也不可能,由於,條件是每次在阿里雲OSS上更新文件時,纔會出現這個問題
,因此,有兩種可能:
而當我分析上面說的302返回的重定向地址時,我不太確信這是一個DNS劫持,由於這地址看起來太正經
,如:
http://111.**.135.171/files/317200004364C385/***.oss-cn-beijing.aliyuncs.com/***.zip
第一段 IP,後面的的路徑很是有規律,files下面的file hash,而後是源站的下載地址。
這麼正經的IP不多是被劫持吧,那麼再說回去,若是302是運營商的DNS緩存致使的,302後的地址也就是這個地址,它是怎麼來的呢??
我分別測試了山東和杭州的網絡,DNS解析***.oss-cn-beijing.aliyuncs.com
這個源下載地址並無返回動態子節點IP,實際上仍是beijing區的源站IP,這說明DNS解析是沒有動態返回節點的。
不是運營商也不是阿里雲,到底是什麼?
愁了我一個星期,在阿里雲棲社區問了此問題,也沒有收到特別準確的回答,由於用戶的問題已經使用其餘方式修復,因此沒有辦法再次肯定問題,目前只能認爲是
DNS解析後的IP是不能直接替換域名的
,DNS是爲了取IP,而IP是在創建鏈接層
之根基,可是鏈接層上還有寫一層,一些服務器上的httpserver,好比Apach或者Nginx會提供一個叫作虛擬站點
的功能,簡單來講根據你請求的host(域名)來分撥出不一樣的文件路徑,也就是說一臺服務器是能夠享有多個域名的。固然不只是分撥路徑,中間還能夠去向其餘服務請求(有點像proxy,可是根據域名來判斷的proxy分撥),想了解更多請搜索 虛擬站點
。
一切惡果毋庸置疑終究是運營商釀造的,可是想繞過它卻不現實。
若是你對於個人問題有其餘見解,請評論。若是你以爲我說的不對,請糾正(有懸賞)。若是你想跳槽,請看個人我的資料右上角。若是你覺還有點幫助,請使勁兒點個贊。若是你以爲這篇文章浪費了你的時間,沒啥乾貨,請私聊噴我一頓。