從輸入網(wǎng)址到最后瀏覽器呈現(xiàn)頁面內(nèi)容

當(dāng)你在瀏覽器中輸入網(wǎng)址(例如www.coder.com)并且敲了回車以后率寡, 瀏覽器首先要做的事情就是獲得coder.com的IP地址伍绳,具體的做法就是發(fā)送一個(gè)UDP的包給DNS服務(wù)器勿她,DNS服務(wù)器會返回coder.com的IP, 這時(shí)候?yàn)g覽器通常會把IP地址給緩存起來,這樣下次訪問就會加快。有了服務(wù)器的IP蝠引, 瀏覽器就要可以發(fā)起HTTP請求了,但是HTTP Request/Response必須在TCP這個(gè)“虛擬的連接”上來發(fā)送和接收蛀柴。

想要建立“虛擬的”TCP連接螃概,TCP郵差需要知道4個(gè)東西:(本機(jī)IP, 本機(jī)端口,服務(wù)器IP, 服務(wù)器端口)鸽疾,現(xiàn)在只知道了本機(jī)IP,服務(wù)器IP吊洼, 兩個(gè)端口怎么辦?本機(jī)端口很簡單制肮,操作系統(tǒng)可以給瀏覽器隨機(jī)分配一個(gè)冒窍, 服務(wù)器端口更簡單,用的是一個(gè)“眾所周知”的端口豺鼻,HTTP服務(wù)就是80综液, 我們直接告訴TCP郵差就行。

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


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

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

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

(2) 可以為每個(gè)請求分配一個(gè)進(jìn)程/線程爪模,但是當(dāng)連接太多的時(shí)候,服務(wù)器端的進(jìn)程/線程會耗費(fèi)大量內(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ù)可讀), 才用一個(gè)進(jìn)程/線程對那個(gè)連接進(jìn)行處理疾呻,處理完以后繼續(xù)監(jiān)視除嘹,等待下次狀態(tài)變化。 用這種方式可以用少量的進(jìn)程/線程應(yīng)對成千上萬的連接請求岸蜗。

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

對于HTTP GET請求,Nginx利用epoll的方式給讀取了出來璃岳, Nginx接下來要判斷年缎,這是個(gè)靜態(tài)的請求還是個(gè)動(dòng)態(tài)的請求啊铃慷?

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

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

例如Ngnix支持這么幾種:

1.輪詢:按照次序挨個(gè)向后端服務(wù)器轉(zhuǎn)發(fā)

2.權(quán)重:給每個(gè)后端服務(wù)器指定一個(gè)權(quán)重镀迂,相當(dāng)于向后端服務(wù)器轉(zhuǎn)發(fā)的幾率内狗。

3.ip_hash: 根據(jù)ip做一個(gè)hash操作怪嫌,然后找個(gè)服務(wù)器轉(zhuǎn)發(fā),這樣的話同一個(gè)客戶端ip總是會轉(zhuǎn)發(fā)? ? ? ? ? ? ? ? ? ? 到同一個(gè)后端服務(wù)器柳沙。

4.fair:根據(jù)后端服務(wù)器的響應(yīng)時(shí)間來分配請求岩灭,響應(yīng)時(shí)間段的優(yōu)先分配。

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

由此可見找爱,Nginx在這種場景下,是一個(gè)代理人的角色泡孩。


Http Request終于來到了Tomcat车摄,這是一個(gè)由Java寫的、可以處理Servlet/JSP的容器仑鸥,我們的代碼就運(yùn)行在這個(gè)容器之中吮播。

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

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

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

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

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

6歸途

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

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

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

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

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

7瀏覽器再次工作

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

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

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

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

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

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

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

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

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

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

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

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

3. JavaScript绎橘, 它可以修改DOM Tree

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

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末熙暴,一起剝皮案震驚了整個(gè)濱河市闺属,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌周霉,老刑警劉巖掂器,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诗眨,居然都是意外死亡唉匾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門匠楚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巍膘,“玉大人,你說我怎么就攤上這事芋簿∠啃福” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵与斤,是天一觀的道長肪康。 經(jīng)常有香客問我荚恶,道長,這世上最難降的妖魔是什么磷支? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任谒撼,我火速辦了婚禮,結(jié)果婚禮上雾狈,老公的妹妹穿的比我還像新娘廓潜。我一直安慰自己,他們只是感情好善榛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布辩蛋。 她就那樣靜靜地躺著,像睡著了一般移盆。 火紅的嫁衣襯著肌膚如雪悼院。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天咒循,我揣著相機(jī)與錄音据途,去河邊找鬼。 笑死剑鞍,一個(gè)胖子當(dāng)著我的面吹牛昨凡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚁署,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼便脊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了光戈?” 一聲冷哼從身側(cè)響起哪痰,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎久妆,沒想到半個(gè)月后晌杰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筷弦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年肋演,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烂琴。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡爹殊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奸绷,到底是詐尸還是另有隱情梗夸,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布号醉,位于F島的核電站反症,受9級特大地震影響辛块,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铅碍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一润绵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胞谈,春花似錦授药、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽莱衩。三九已至爵嗅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間笨蚁,已是汗流浹背睹晒。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留括细,地道東北人伪很。 一個(gè)月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像奋单,于是被迫代替她去往敵國和親锉试。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容