一個域名如果對應多個IP,那麼實際訪問這個域名會訪問到哪個IP哪台伺服器呢?
一個域名可以解析出幾個IP地址,例如在訪問www.163.com時,抓包得到的DNS響應包中有2個IP地址:221.229.167.47和58.220.39.91,如下圖所示。
雖然DNS解析得到了多個IP,但是大多數軟體只會使用第一個IP地址,這是什麼原因?
TCP/IP網路通信是基於IP地址的,當要訪問的伺服器地址是域名時,就需要先把域名解析成IP地址。在TCP/IP API中有一個叫gethostbyname的函數,負責把域名解析成IP地址。 函數的原型定義如下,參數name就是要解析的域名。
struct hostent *gethostbyname(const char *name);
函數的返回值為一個結構體指針,這個結構體的定義為:
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}
#define h_addr h_addr_list[0] /* for backward compatibility */
結構體中的h_addr_list是一個數組,用於存放解析出的多個IP地址,但很少有程序員會去考慮多個IP地址的問題,通常直接使用宏h_addr來獲取IP地址,也就是第一個IP地址。
一些大型網站或CDN服務商為了實現負載均衡,他們的DNS伺服器會動態改變多個IP地址的順序,使得每個IP地址都有機會成為解析結果中的第一個IP地址。
下面的小程序可以列印出解析www.163.com得到的第一個IP地址,多次運行這個程序,IP地址是交替的。
#include &
#include &
#include &
#include &
int main()
{
struct hostent *host;
struct in_addr h_addr;
if ((host = gethostbyname("www.163.com")) != NULL) {
h_addr.s_addr = *((unsigned long *) host-&>h_addr);
printf("%s
", inet_ntoa(h_addr));
}
return 0;
}
瀉藥,這個是屬於就近IP地址訪問的演算法,當我一個IP到DNS上面請求DNS域名解析的時候,DNS系統會根據你的IP地址所到達的域名對應的IP地址中路由跳數最小的那個IP地址作為訪問的IP地址,具體你可以用LINUX的NSLOOKUP來查看域名所對應的IP地址,然後用PC的TRACERT的功能把所有DNS解析出來的IP地址進行跳數記錄,然後在訪問該域名,查看具體是哪個地址解析給你的PC。
比如百度,你會發現他上面實際解析出來的不是IP地址,而是 http://www.a.shifen.com這個域名,這個域名往下面去才是IP地址,而我估計,這個域名應該是百度自建的一個域名系統,最重要的作用就是指定你的IP所訪問百度這個網址會使用到哪個IP地址,而使用CNAME有個好處就是,我IP地址去做改動的時候不需要去DNS運營商上面做改動,只需要自己的伺服器做改動就好,方便自己的域名與實際IP地址做對應。
以上。
- 在域名解析過程中,通過層層解析,必將域名對應到 IP
(逐級授權、中間 CNAME 層層轉發,此處按下不表) - 對於對應到的IP,可能1個,也可能13個(不建議超過13個),DNS 會一股腦將這(些)個 IP 給解析客戶端(如瀏覽器、操作系統的解析服務)
- 最終的應用或系統解析服務,從中隨機挑選一個
(如果是定製的應用,還可以通過後續的應用層訪問對獲取到的 IP 做 HA 或權重)
不知道樓上的大神都在回答什麼,何必搞得這麼複雜?不就是負載均衡問題么!
推薦閱讀:
※IP和域名之間是怎麼樣的映射關係,一對一,一對多還是多對一?
※alexa排名較高的org後綴的網站有哪些?
※有人出80萬購買我們項目的域名,值得賣嗎?
※我們要用13萬來買一個域名,這麼多錢貴嗎?
※如何註冊 .us 域名?