小白科普:從輸入網址到最後瀏覽器呈現頁面內容,中間發生了什麼?
老劉
1前言這篇文章是應網友之邀所寫,主要描述一下我們訪問網站時, 從輸入網址到最後瀏覽器呈現內容,中間發生了什麼。今天的文章主要專註於應用層,我拿了一個很簡單的網路結構來講。假定本機已經獲取了IP地址,各種網路基礎設施已經準備好了。由於知識點太多,我肯定會漏掉部分內容,歡迎在留言中補充, 以後我會根據大家建議再寫文章擴展。
2準備當你在瀏覽器中輸入網址(例如http://www.coder.com)並且敲了回車以後, 瀏覽器首先要做的事情就是獲得http://coder.com的IP地址,具體的做法就是發送一個UDP的包給DNS伺服器,DNS伺服器會返回http://coder.com的IP, 這時候瀏覽器通常會把IP地址給緩存起來,這樣下次訪問就會加快。比如Chrome, 你可以通過chrome://net-internals/#dns來查看。有了伺服器的IP, 瀏覽器就要可以發起HTTP請求了,但是HTTP Request/Response必須在TCP這個「虛擬的連接」上來發送和接收。想要建立「虛擬的」TCP連接,TCP郵差需要知道4個東西:(本機IP, 本機埠,伺服器IP, 伺服器埠),現在只知道了本機IP,伺服器IP, 兩個埠怎麼辦?本機埠很簡單,操作系統可以給瀏覽器隨機分配一個, 伺服器埠更簡單,用的是一個「眾所周知」的埠,HTTP服務就是80, 我們直接告訴TCP郵差就行。經過三次握手以後,客戶端和伺服器端的TCP連接就建立起來了! 終於可以發送HTTP請求了。對於HTTP GET請求,Nginx利用epoll的方式給讀取了出來, Nginx接下來要判斷,這是個靜態的請求還是個動態的請求啊?
如果是靜態的請求(HTML文件,JavaScript文件,CSS文件,圖片等),也許自己就能搞定了(當然依賴於Nginx配置,可能轉發到別的緩存伺服器去),讀取本機硬碟上的相關文件,直接返回。如果是動態的請求,需要後端伺服器(如Tomcat)處理以後才能返回,那就需要向Tomcat轉發,如果後端的Tomcat還不止一個,那就需要按照某種策略選取一個。例如Ngnix支持這麼幾種:- 輪詢:按照次序挨個向後端伺服器轉發
- 權重:給每個後端伺服器指定一個權重,相當於向後端伺服器轉發的幾率。
- ip_hash: 根據ip做一個hash操作,然後找個伺服器轉發,這樣的話同一個客戶端ip總是會轉發到同一個後端伺服器。
- fair:根據後端伺服器的響應時間來分配請求,響應時間段的優先分配。
由此可見,Nginx在這種場景下,是一個代理人的角色。
剩下的故事就比較簡單了(不,對碼農來說,其實是最複雜的部分),就是執行碼農經常寫的增刪改查邏輯,在這個過程中很有可能和緩存、資料庫等後端組件打交道,最終返回HTTP Response,由於細節依賴業務邏輯,略去不表。
根據我們的例子,這個HTTP Response應該是一個HTML頁面。5歸途Tomcat很高興地把Http Response發給了Ngnix 。Ngnix也很高興地把Http Response 發給了瀏覽器。如果是HTTP1.0,要看看之前的HTTP Request Header中有沒有Connetion:keep-alive,如果有,那也不能關閉。
6瀏覽器再次工作瀏覽器收到了Http Response,從其中讀取了HTML頁面,開始準備顯示這個頁面。但是這個HTML頁面中可能引用了大量其他資源,例如js文件,CSS文件,圖片等,這些資源也位於伺服器端,並且可能位於另外一個域名下面,例如http://static.coder.com。瀏覽器沒有辦法,只好一個個地下載,從使用DNS獲取IP開始,之前做過的事情還要再來一遍。不同之處在於不會再有應用伺服器如Tomcat的介入了。如果需要下載的外部資源太多,瀏覽器會創建多個TCP連接,並行地去下載。但是同一時間對同一域名下的請求數量也不能太多,要不然伺服器訪問量太大,受不了。所以瀏覽器要限制一下, 例如Chrome在Http1.1下只能並行地下載6個資源。當伺服器給瀏覽器發送JS,CSS這些文件時,會告訴瀏覽器這些文件什麼時候過期(使用Cache-Control或者Expire),瀏覽器可以把文件緩存到本地,當第二次請求同樣的文件時,如果不過期,直接從本地取就可以了。
如果過期了,瀏覽器就可以詢問伺服器端,文件有沒有修改過?(依據是上一次伺服器發送的Last-Modified和ETag),如果沒有修改過(304 Not Modified),還可以使用緩存。否則的話伺服器就會被最新的文件發回到瀏覽器。當然如果你按了Ctrl+F5,會強制地發出GET請求,完全無視緩存。註:在Chrome下,可以通過 chrome://view-http-cache/ 命令來查看緩存。現在瀏覽器得到了三個重要的東西:1.HTML ,瀏覽器把它變成DOM Tree2. CSS, 瀏覽器把它變成CSS Rule Tree3. JavaScript, 它可以修改DOM Tree瀏覽器會通過DOM Tree和CSS Rule Tree生成所謂「Render Tree」,計算每個元素的位置/大小,進行佈局,然後調用操作系統的API進行繪製,這是一個非常複雜的過程,略去不表。到目前為止,我們終於在瀏覽器中看到了http://www.coder.com的內容。本文轉自公眾號:碼農翻身
推薦閱讀: