當你在瀏覽器輸入一個網址,回車後究竟發生了什麼?

凌峰發表於2018-03-08
當你在瀏覽器輸入一個網址回車後究竟發生了什麼?其實這可以作為一個面試題來考察候選人了,我也被問過類似的問題,這裡書面化下,方便記憶。

首先分析下這個問題想要問的是什麼,其實這個問題可以回答的很深,也可以回答的很淺,這裡按我個人的思路來回答,結合圖表方便理解。


  • 1、瀏覽器做了什麼?

瀏覽器接收到使用者輸入的地址後做了什麼,可以通過chrome的一個工具timing來看,往往這也是分析一個頁面的效能的一個輔助工具,以我在瀏覽器輸入的網址為:http://cxf.apache.org/docs/cxf-architecture.html為例,timing結果如圖:

第一步Resource Scheduling,也就是資源排程,可以把這個操作看成一個JOB,瀏覽器有個任務佇列,要先將這個JOB放到Queue裡,圖中可以看出從放入佇列到被排程執行中間隔了23.56毫秒。

第二步Connection Start,也就是建立連線,其中又分為好幾步,Stalled裡是檢查瀏覽器有沒有設定網路代理,有沒有可以用的連線,DNS Lookup是DNS查詢,而Initial connection則顯示了從開始檢查代理,獲取連線,DNS查詢,TCP握手,到建立好TCP連線的總時間。

第三步Request/Response,這個就是我們最關心的了,這裡包括請求的傳送,等待後端的響應,下載當前資原始檔。Request sent就是上傳請求,這裡有很多可以再細講的東西,但這些想想其實都是HTTP協議裡的內容了,就不在這裡多說了,後面再單獨寫篇談談。接下來詳細猜下Waiting(TTFB)裡做了什麼。

  • 2、伺服器做了什麼?

伺服器做了什麼也是因情況而定的,有的很簡單,有的則比較複雜,這裡常規的談談。

1)伺服器防火牆,這裡是為了保護服務而設定的,這裡可以有效的拒覺不合理的請求,讓服務可以正常地給需要的人使用,但並不是所有的網站都存在。

2)域名伺服器,還以上面我在瀏覽器中輸入的地址為例,cxf是apache.org的子域名,請求先到apache.org,再通過域名伺服器查詢cxf.apache.org的真正IP,再根據IP找到對應的伺服器。

3)負載均衡器,一般為了能夠為更多的使用者服務,一個域名背後可能是多個伺服器,那麼一次請求最終由誰來處理,這就由負載均衡來決定。負載均衡其實也有好多可以聊的,這個也後面單獨寫文章聊吧,比方如何處理帶session的,各種負載均衡演算法的適用場景,常用的負載均衡工具(硬體負載均衡與軟體負載均衡)。

4)Servlet容器/Web容器,有些應用是直接使用的Servlet容器,把頁面用類似velocity的模板引擎來轉換,這就帶來一個問題,一次請求這些Document就要經過Servlet容器來傳輸,可想servlet的負擔就重了。一些聰明點的應用就會在Servlet容器前再放一個Web容器,比如Apache或Nginx或者Node,把不變的Document放在Apache上,把只需要變化的資料讓Servlet來處理。

5)快取服務,主要因為磁碟和記憶體的讀寫速度相差太多數量級,所以將資料區分冷熱,冷的放磁碟,熱的放記憶體。但快取設計的好與不好起決定性作用,命中率高則可以改善系統的響應速度,命中率低則形同虛設。

6)資料庫,負責資料的持久化,使用者的一些資料有些時候是需要儲存下來,這裡就要有可用性的設計了,講白了就是一個專門儲存檔案的機器,同時還提供查詢和更新檔案的功能,為了有效的管理,形成了專門的應用:資料庫。

7)搜尋引擎,這其實也算是“資料庫”的一種形態了,只不過它的專長是查詢,查詢檔案特別快,主要還是因為最開始設計的管理檔案的應用在資料量大了以後各種問題都出來了,這才有了搜尋引擎,搜尋引擎的索引設計和資料庫的索引設計比起來明顯簡單很多。

  • 3、瀏覽器接收到Respone後又做了什麼?

其實瀏覽接收到Document內容後還做了一些事情,這些其實是前端可以優化頁面的地方,包括資原始檔的下載,文件的解析與頁面的渲染,還有CDN起到的作用。

1)瀏覽器的執行緒,瀏覽器下載documet會邊下載邊解析,當然可能不是同一個執行緒來做,比如document裡引入了CSS和JS還有圖片這些資源,那麼瀏覽器會起多執行緒的方式來下載這些資原始檔。

2)先下載CSS,由於頁面是依賴CSS來渲染出來的,所以如果想要頁面早一點被渲染,那就要讓CSS早一點下載完,CSS下載完後還要生成樣式。

3)減少下載次數,合併下載可以有效地減少網路建立帶來的耗時,JS可以合併、CSS可以合併、圖片也可以合併。

4)減少下載內容,壓縮資原始檔可以減少頻寬耗時。

5)利用CDN縮短請求鏈路,靜態資原始檔和多媒體檔案儘量放CDN上,請求優先訪問CDN,當然這個是有一定成本的,而且如果內容有更新還要同步推送更新到CDN,但是現在CDN運營商比較多,網路覆蓋也比較廣。

  • 4、從網路知識的角度分析

1)瀏覽器與伺服器建立TCP請求連線,因為在網路中標識主機的是MAC地址,MAC地址和IP的相互轉換是通過ARP和RARP,TCP的報文會由網路中的路由器傳遞到指定的主機中,每個路由器都有一份路由表。這個有點像寄快遞,每個地方的郵編就像是IP(當然現在郵編的用處可能已經在淡化),郵編又對應著具體的地址,郵局的中轉站對應的是路由器,包裹就是TCP報文,當包裹到一箇中轉站時,是中轉站會判斷這個包裹要發往的下個站點是哪,而路由器判斷的標準則是路由表,路由表資訊會實時更新,當然,實際路由器中的路由演算法還是比我說的要複雜的。伺服器接收到TCP報文的位元組碼後會拆包,將報文組裝成對應的協議,這裡是需要約定編碼方式的,但這在HTTP協議裡已經有了,伺服器需要按照協議來解碼。當然,寄一次快遞是單向的資料流,而一次HTTP請求是有Response的,有點像現實生活中快遞包裹被拒收退會,再次流轉到寄件人手中。當然這個比喻不是很精準,因為計算機網路中要比寄快遞流程複雜多的多。

2)Java一般都是將HTTP再轉成Servlet物件來處理的,這也是為什麼會有Tomcat/Jetty等應用容器了,通常Servlet對應的不是單次的HTTP請求,Servlet中還有Session,這也是為什麼要有Servlet的原因。

3)實際中伺服器的網路也是比較複雜,尤其在有了雲端計算和虛擬化技術後,對於虛擬化技術中的網路問題目前還在持續探索中,可能還有很多比當前共享的方式還好的方法,但有時候成本還是很重要的,並不是所有的技術都適合應用,決定能否應用的重要因素是成本在接收範圍內。

4)可能的效能瓶頸:頻寬、網路卡、DNS伺服器、負載均衡、磁碟操作、等等

  • 5、在IOT應用中發生了什麼?

剛畢業時幫一個同事做了一個畢業設計的demo,大方向是智慧家居相關,但實際只做了一個簡單的Demo,最終實現的效果就是一個開發板和電腦相連,在電腦的瀏覽器中輸入一個網址,網頁上有個按鈕,點一下這個按鈕,就可以把燈關閉或開啟。這裡其實就和上面有所不同了,後面其實並沒有上面那麼複雜的結構,沒有伺服器,也沒有作業系統,開發板還是一個51微控制器開發板,這裡輸入網址後就比較簡單,微控制器只需要對網路流中的內容進行相應的解析和返回,不存在Servlet,返回頁面也是直接拼出來的Document,程式碼寫死的,這裡就是微控制器直接和網路卡互動了,然後就按照網路裡的各個協議進行解析和組裝,最後響應的其實就是一個PORT口,用高低電平也就是0和1來控制外設,外設用的繼電器,從而達到使燈關閉和開啟。

相關文章