當我們從瀏覽器輸入某個域名(如:http://www.baidu.com ),到服務器返回結果給瀏覽器為止捆蜀,這個過程究竟發(fā)生了什么当宴,又涉及到了哪些技術埠偿。本文談談自己對這一過程的理解。
1. B/S 網(wǎng)絡總體結構
目前 B/S 網(wǎng)絡的總體架構大概如下圖所示:
當一個用戶在瀏覽器輸入 http://www.baidu.com 這個 URL 時要门,首先瀏覽器會請求 DNS 把這個域名解析成對應的 IP 地址 虏肾,然后根據(jù)這個 IP 地址找到對應的服務器廓啊,向目標服務器發(fā)起一個 get 請求,由這個目標服務器決定返回什么數(shù)據(jù)資源給訪問的用戶封豪。在這個過程中崖瞭,服務器端還有很多復雜的業(yè)務邏輯:服務器可能不止一臺,到底有哪臺服務器來處理這個請求撑毛,這需要一個負載均衡設備來平均分配所有的用戶請求书聚;還有請求的數(shù)據(jù)可能存在分布式緩存里,也可能存在靜態(tài)文件里藻雌,還有可能存在數(shù)據(jù)庫雌续;當數(shù)據(jù)返回給瀏覽器時,瀏覽器發(fā)現(xiàn)含有一些靜態(tài)資源時胯杭,瀏覽器又會發(fā)起另外的 HTTP 請求驯杜,而這些請求很可能會在 CDN 上,CDN 服務器又會處理這些請求做个。這個過程中的每一個細節(jié)都會決定這個請求是否成功鸽心。
2. 如何發(fā)起一個 HTTP 請求
發(fā)起一個 HTTP 請求和建立一個 Socket 連接的區(qū)別不大,只不過 outputStream.write 寫的二進制數(shù)據(jù)格式要符合 HTTP居暖。瀏覽器在建立 Socket 連接之前顽频,必須根據(jù)地址欄輸入的 URL 的域名 DNS 解析出 IP 地址,再根據(jù)這個 IP 地址和默認的80端口遠程服務器建立 Socket 連接太闺,然后瀏覽器根據(jù)這個 URL 組裝成一個 get 類型的 HTTP 請求頭糯景,通過 outputStream.write 發(fā)送到目標服務器,服務器等待 inputStream.read 返回數(shù)據(jù)省骂,最后斷開這個連接蟀淮。
3. 如何解析 HTTP
這里只介紹下常用的 HTTP 請求頭、響應頭钞澳、狀態(tài)碼以及緩存機制怠惶。
請求頭 | 說明 |
---|---|
Accept-Charset | 用于指定客戶端接受的字符集 |
Accept-Encoding | 用于指定可接受的內(nèi)容編碼,如 Accept-Encoding:gzip.deflate |
Accept-Language | 用于指定一種自然語言轧粟,如 Accept-Language:zh-cn |
Host | 用于指定被請求資源的 Internet 主機和端口號策治,如 Host:www.baidu.com |
User-Agent | 客戶端將它的操作系統(tǒng)、瀏覽器和其他屬性告訴服務器 |
Connection | 當前連接是否保持逃延,如:Connection:Keep-Alive |
響應頭 | 說明 |
---|---|
Server | 使用的服務器名稱览妖,如 Server:Apache/1.3.6(Unix) |
Content-Type | 用來指明發(fā)送給接受者的實體正文的媒體類型,如 Content-Type:text/html;charset=GBK |
Content-Language | 描述了資源所用的自然語言揽祥,與 Accept-Language 對應 |
Content-Encoding | 與請求報頭 Accept-Encoding 對應讽膏,告訴瀏覽器服務端采用的是什么壓縮編碼 |
Content-Length | 指明實體正文的長度,用以志杰方式存儲的十進制數(shù)字來表示 |
Keep-Alive | 保持連接的時間拄丰,如:Keep-Alive: timeout=5, max=120 |
狀態(tài)碼 | 說明 |
---|---|
200 | 客戶端請求成功 |
302 | 臨時跳轉府树,跳轉的地址通過 Location 指定 |
400 | 客戶端請求有語法錯誤俐末,不能被服務器識別 |
403 | 服務器收到請求,但是拒絕提供服務 |
404 | 請求的資源不存在 |
500 | 服務器發(fā)生不可預期的錯誤 |
緩存設置 | 說明 |
---|---|
Cache-Control | 請求字段優(yōu)先級較高奄侠,使用如 Cache-Control: no-cache |
Pragma | 和 Cache-Control 作用類似卓箫,最常用的是 Pragma: no-cache |
Expires | Expires 后面跟著一個日期和時間,超過這個時間緩存的內(nèi)容將失效 |
Last-Modified | 服務器上的資源最后修改時間 |
Etag | 服務端給每個頁面分配一個唯一的編號垄潮,通過編號來區(qū)分當前頁面是否是最新的 |
4. DNS 域名解析的過程
DNS 域名解析的大致過程如下圖所示:
1. 瀏覽器會檢查緩存中是否有該域名對應的 IP 地址解析結果烹卒,如果緩存中有,這個解析過程就將結束弯洗。
2. 如果用戶的瀏覽器緩存中沒有旅急,瀏覽器會查找操作系統(tǒng)緩存中是否有這個域名對應的 DNS 解析結果。
3. 如果用戶操作系統(tǒng)緩存中沒有牡整,操作系統(tǒng)會把這個域名發(fā)送給 LDNS藐吮,也就是本地區(qū)的域名服務器。
4. 如果 LDNS 仍然沒有命中逃贝,就直接到 Root Server 域名服務器請求解析谣辞。
5. 根域名服務器返回給本地域名服務器一個所查詢域的主域名服務器(gTLD Server)地址。
6. 本地域名服務器(LDNS)再向上一步返回的 gTLD 服務器發(fā)送請求沐扳。
7. 接受請求的 gTLD 服務器查找并返回此域名對應的 Name Server 域名服務器地址泥从,這個 Name Server 通常就是你注冊的域名服務器。
8. Name Server 域名服務器會查詢存儲的域名和 IP 的映射關系表迫皱,在正常情況下都根據(jù)域名得到目標 IP 記錄歉闰,連同一個 TTL 指返回給 DNS Server 域名服務器。
9. 返回該域名對應的 IP 和 TTL 值卓起,LDNS 會緩存這個域名和 IP 的對應關系,緩存的時間由 TTL 值控制凹炸。
10. 把解析的結果返回給用戶戏阅,用戶根據(jù) TTL 值緩存在本地系統(tǒng)緩存中,域名解析過程到此結束啤它。
5. 幾種域名解析方式
- A 記錄:A 代表的是 Address奕筐,用來指定域名對應的 IP 地址。
- MX 記錄:表示的是 Mail Exchange变骡,就是可以將某個域名下的郵件服務器指向自己的 Mail Server离赫。
- CNAME 記錄:全稱是 Canonical Name(別名解析),就是可以為一個域名設置一個或者多個別名塌碌。
- NS 記錄:為某個域名指定 DNS 解析服務器渊胸。
- TXT 記錄:為某個主機名或域名設置說明。
6. 何謂 CDN
CDN 也就是內(nèi)容分布網(wǎng)絡(Content Delivery Network),目的就是使用戶可以就近取得所需的內(nèi)容台妆,提高用戶訪問網(wǎng)絡的響應速度翎猛。