自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

小白科普:從輸入網(wǎng)址到最后瀏覽器呈現(xiàn)頁面內(nèi)容,中間發(fā)生了什么?

開發(fā) 開發(fā)工具 瀏覽器
這篇文章是應(yīng)網(wǎng)友之邀所寫,主要描述一下我們訪問網(wǎng)站時, 從輸入網(wǎng)址到最后瀏覽器呈現(xiàn)內(nèi)容,中間發(fā)生了什么。

[[215917]]

1.前言

這篇文章是應(yīng)網(wǎng)友之邀所寫,主要描述一下我們訪問網(wǎng)站時, 從輸入網(wǎng)址到最后瀏覽器呈現(xiàn)內(nèi)容,中間發(fā)生了什么。

之前寫過兩篇文章《我是一個網(wǎng)卡》,《我是一個路由器》描述了一個電腦如何通過DHCP、ARP、NAT等上式獲取IP、然后訪問網(wǎng)絡(luò)的過程,主要專注在傳輸層和網(wǎng)絡(luò)層。

今天的文章主要專注于應(yīng)用層,我拿了一個很簡單的網(wǎng)絡(luò)結(jié)構(gòu)來講。假定本機已經(jīng)獲取了IP地址,各種網(wǎng)絡(luò)基礎(chǔ)設(shè)施已經(jīng)準(zhǔn)備好了。

由于知識點太多,我肯定會漏掉部分內(nèi)容,歡迎在留言中補充, 以后我會根據(jù)大家建議再寫文章擴(kuò)展。

2.準(zhǔn)備

當(dāng)你在瀏覽器中輸入網(wǎng)址(例如www.coder.com)并且敲了回車以后, 瀏覽器首先要做的事情就是獲得coder.com的IP地址,具體的做法就是發(fā)送一個UDP的包給DNS服務(wù)器,DNS服務(wù)器會返回coder.com的IP, 這時候瀏覽器通常會把IP地址給緩存起來,這樣下次訪問就會加快。

比如Chrome, 你可以通過chrome://net-internals/#dns來查看。

有了服務(wù)器的IP, 瀏覽器就要可以發(fā)起HTTP請求了,但是HTTP Request/Response必須在TCP這個“虛擬的連接”上來發(fā)送和接收。

想要建立“虛擬的”TCP連接,TCP郵差需要知道4個東西:(本機IP, 本機端口,服務(wù)器IP, 服務(wù)器端口),現(xiàn)在只知道了本機IP,服務(wù)器IP, 兩個端口怎么辦?

本機端口很簡單,操作系統(tǒng)可以給瀏覽器隨機分配一個, 服務(wù)器端口更簡單,用的是一個“眾所周知”的端口,HTTP服務(wù)就是80, 我們直接告訴TCP郵差就行。

經(jīng)過三次握手以后,客戶端和服務(wù)器端的TCP連接就建立起來了! 終于可以發(fā)送HTTP請求了。

之所以把TCP連接畫成虛線,是因為這個連接是虛擬的, 詳情可參見之前的文章《TCP/IP之大明郵差》,《張大胖的Socket

3.Web服務(wù)器

一個HTTP GET請求經(jīng)過千山萬水,歷經(jīng)多個路由器的轉(zhuǎn)發(fā),終于到達(dá)服務(wù)器端(HTTP數(shù)據(jù)包可能被下層進(jìn)行分片傳輸,略去不表)。

Web服務(wù)器需要著手處理了,它有三種方式來處理:

(1) 可以用一個線程來處理所有請求,同一時刻只能處理一個,這種結(jié)構(gòu)易于實現(xiàn),但是這樣會造成嚴(yán)重的性能問題。

(2) 可以為每個請求分配一個進(jìn)程/線程,但是當(dāng)連接太多的時候,服務(wù)器端的進(jìn)程/線程會耗費大量內(nèi)存資源,進(jìn)程/線程的切換也會讓CPU不堪重負(fù)。

(3) 復(fù)用I/O的方式,很多Web服務(wù)器都采用了復(fù)用結(jié)構(gòu),例如通過epoll的方式監(jiān)視所有的連接,當(dāng)連接的狀態(tài)發(fā)生變化(如有數(shù)據(jù)可讀), 才用一個進(jìn)程/線程對那個連接進(jìn)行處理,處理完以后繼續(xù)監(jiān)視,等待下次狀態(tài)變化。 用這種方式可以用少量的進(jìn)程/線程應(yīng)對成千上萬的連接請求。

(碼農(nóng)翻身注:詳情參見《Http Server:一個差生的逆襲》)

我們使用Nginx這個非常流行的Web服務(wù)器來繼續(xù)下面的故事。

對于HTTP GET請求,Nginx利用epoll的方式給讀取了出來, Nginx接下來要判斷,這是個靜態(tài)的請求還是個動態(tài)的請求???

如果是靜態(tài)的請求(HTML文件,JavaScript文件,CSS文件,圖片等),也許自己就能搞定了(當(dāng)然依賴于Nginx配置,可能轉(zhuǎn)發(fā)到別的緩存服務(wù)器去),讀取本機硬盤上的相關(guān)文件,直接返回。

如果是動態(tài)的請求,需要后端服務(wù)器(如Tomcat)處理以后才能返回,那就需要向Tomcat轉(zhuǎn)發(fā),如果后端的Tomcat還不止一個,那就需要按照某種策略選取一個。

例如Ngnix支持這么幾種:

  • 輪詢:按照次序挨個向后端服務(wù)器轉(zhuǎn)發(fā)
  • 權(quán)重:給每個后端服務(wù)器指定一個權(quán)重,相當(dāng)于向后端服務(wù)器轉(zhuǎn)發(fā)的幾率。
  • ip_hash: 根據(jù)ip做一個hash操作,然后找個服務(wù)器轉(zhuǎn)發(fā),這樣的話同一個客戶端ip總是會轉(zhuǎn)發(fā)到同一個后端服務(wù)器。
  • fair:根據(jù)后端服務(wù)器的響應(yīng)時間來分配請求,響應(yīng)時間段的優(yōu)先分配。

不管用哪種算法,某個后端服務(wù)器最終被選中,然后Nginx需要把HTTP Request轉(zhuǎn)發(fā)給后端的Tomcat,并且把Tomcat輸出的HttpResponse再轉(zhuǎn)發(fā)給瀏覽器。

由此可見,Nginx在這種場景下,是一個代理人的角色。

5.應(yīng)用服務(wù)器

Http Request終于來到了Tomcat,這是一個由Java寫的、可以處理Servlet/JSP的容器,我們的代碼就運行在這個容器之中。

如同Web服務(wù)器一樣, Tomcat也可能為每個請求分配一個線程去處理,即通常所說的BIO模式(Blocking I/O 模式)。

也可能使用I/O多路復(fù)用技術(shù),僅僅使用若干線程來處理所有請求,即NIO模式。

不管用哪種方式,Http Request 都會被交給某個Servlet處理,這個Servlet又會把Http Request做轉(zhuǎn)換,變成框架所使用的參數(shù)格式,然后分發(fā)給某個Controller(如果你是在用Spring)或者Action(如果你是在Struts)。

剩下的故事就比較簡單了(不,對碼農(nóng)來說,其實是最復(fù)雜的部分),就是執(zhí)行碼農(nóng)經(jīng)常寫的增刪改查邏輯,在這個過程中很有可能和緩存、數(shù)據(jù)庫等后端組件打交道,最終返回HTTP Response,由于細(xì)節(jié)依賴業(yè)務(wù)邏輯,略去不表。

根據(jù)我們的例子,這個HTTP Response應(yīng)該是一個HTML頁面。

6.歸途

Tomcat很高興地把Http Response發(fā)給了Ngnix 。

Ngnix也很高興地把Http Response 發(fā)給了瀏覽器。

發(fā)完以后TCP連接能關(guān)閉嗎?

如果使用的是HTTP1.1, 這個連接默認(rèn)是keep-alive,也就是說不能關(guān)閉;

如果是HTTP1.0,要看看之前的HTTP Request Header中有沒有Connetion:keep-alive,如果有,那也不能關(guān)閉。

7.瀏覽器再次工作

瀏覽器收到了Http Response,從其中讀取了HTML頁面,開始準(zhǔn)備顯示這個頁面。

但是這個HTML頁面中可能引用了大量其他資源,例如js文件,CSS文件,圖片等,這些資源也位于服務(wù)器端,并且可能位于另外一個域名下面,例如static.coder.com。

瀏覽器沒有辦法,只好一個個地下載,從使用DNS獲取IP開始,之前做過的事情還要再來一遍。不同之處在于不會再有應(yīng)用服務(wù)器如Tomcat的介入了。

如果需要下載的外部資源太多,瀏覽器會創(chuàng)建多個TCP連接,并行地去下載。

但是同一時間對同一域名下的請求數(shù)量也不能太多,要不然服務(wù)器訪問量太大,受不了。所以瀏覽器要限制一下, 例如Chrome在Http1.1下只能并行地下載6個資源。

當(dāng)服務(wù)器給瀏覽器發(fā)送JS,CSS這些文件時,會告訴瀏覽器這些文件什么時候過期(使用Cache-Control或者Expire),瀏覽器可以把文件緩存到本地,當(dāng)?shù)诙握埱笸瑯拥奈募r,如果不過期,直接從本地取就可以了。

如果過期了,瀏覽器就可以詢問服務(wù)器端,文件有沒有修改過?(依據(jù)是上一次服務(wù)器發(fā)送的Last-Modified和ETag),如果沒有修改過(304 Not Modified),還可以使用緩存。否則的話服務(wù)器就會被最新的文件發(fā)回到瀏覽器。

當(dāng)然如果你按了Ctrl+F5,會強制地發(fā)出GET請求,完全無視緩存。

注:在Chrome下,可以通過 chrome://view-http-cache/ 命令來查看緩存。

現(xiàn)在瀏覽器得到了三個重要的東西:

1.HTML ,瀏覽器把它變成DOM Tree

2. CSS,  瀏覽器把它變成CSS Rule Tree

3. JavaScript, 它可以修改DOM Tree

瀏覽器會通過DOM Tree和CSS Rule Tree生成所謂“Render Tree”,計算每個元素的位置/大小,進(jìn)行布局,然后調(diào)用操作系統(tǒng)的API進(jìn)行繪制,這是一個非常復(fù)雜的過程,略去不表。

到目前為止,我們終于在瀏覽器中看到了www.coder.com的內(nèi)容。

【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號coderising獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2020-09-01 11:40:01

HTTPJavaTCP

2022-03-04 08:56:58

HTTPDNS 服務(wù)器瀏覽器

2020-10-09 08:59:55

輸入網(wǎng)址解密

2010-07-06 10:11:25

瀏覽器

2020-03-18 08:56:27

頁面網(wǎng)址內(nèi)容

2024-11-04 09:10:00

2021-04-14 10:47:56

瀏覽器網(wǎng)址TCP

2024-05-06 10:53:22

瀏覽器TCPHTTPS

2023-01-14 16:11:27

瀏覽器URL回車

2024-11-04 08:10:00

2017-09-22 13:24:20

2020-01-10 08:54:24

URLDNSTCP

2017-04-11 13:54:49

HTTPURLHTML

2022-04-28 07:52:05

HTTP瀏覽器

2022-05-26 23:36:36

SQLMySQL數(shù)據(jù)

2024-11-04 10:00:00

瀏覽器網(wǎng)絡(luò)

2024-11-22 16:20:28

2024-04-11 08:33:25

2023-10-30 23:14:57

瀏覽器URL網(wǎng)頁

2023-11-02 08:00:00

ClickHouse數(shù)據(jù)庫
點贊
收藏

51CTO技術(shù)棧公眾號