在我們點擊一個網址,到它能夠呈現在瀏覽器中,展示在我們面前,這個過程中,電腦里,網絡上,究竟發生了什么事情。
服務器啟動監聽模式
那我們就開始了,故事其實并不是從在瀏覽器的地址欄輸入一個網址,或者我們抓著鼠標點擊一個鏈接開始,事情的開端要追溯到服務器啟動監聽服務的時候,在某個未知的時刻,一臺機房里普普通通的刀片服務器,加上電,啟動了操作系統,隨著操作系統的就緒,服務器啟動了 http 服務進程,這個 http 服務的守護進程,(),可能是 ,也可能是 nginx,不管怎么說,這個 http 服務進程開始定位到服務器上的 www 文件夾,一般是位于 /var/www ,然后啟動了一些附屬的模塊,例如 php,或者,使用 方式連接到 php 的 fpm 管理進程,然后,向操作系統申請了一個 tcp 連接,然后綁定在了 80 端口,調用了 函數,開始了默默的監聽,監聽著可能來自位于地球任何一個地方的請求,隨時準備做出響應。
這個時候,典型的情況下,機房里面應該還有一個數據庫服務器,或許,還有一臺緩存服務器,如果對于流量巨大的網站,那么動態腳本的解釋器可能還有單獨的物理機器來跑,如果是中小的站點,那么,上述的各色服務,甚至都可能在一臺物理機上,這些服務監聽之間的關系。不管怎么說,他們做好了準備,靜候差遣。
客戶端瀏覽器發送請求1. 解析URL2. 輸入的是 URL 還是搜索的關鍵字?
當協議或主機名不合法時,瀏覽器會將地址欄中輸入的文字傳給默認的搜索引擎。大部分情況下,在把文字傳遞給搜索引擎的時候,URL會帶有特定的一串字符,用來告訴搜索引擎這次搜索來自這個特定瀏覽器。
3. 轉換非 ASCII 的 字符5. dns查詢6. ARP 過程
要想發送 ARP(地址解析協議)廣播,我們需要有一個目標 IP 地址,同時還需要知道用于發送 ARP 廣播的接口的 MAC 地址。
我們發送一個二層( OSI 模型 中的數據鏈路層)ARP 請求:
ARP :
1
2
3
4
MAC: :mac::here
IP: .ip.goes.here
MAC: FF:FF:FF:FF:FF:FF ()
IP: .ip.goes.here
根據連接主機和路由器的硬件類型不同,可以分為以下幾種情況:
直連:
集線器:
ARP Reply:
1
2
3
4
MAC: :mac::here
IP: .ip.goes.here
MAC: :mac::here
IP: .ip.goes.here
現在我們有了 DNS 服務器或者默認網關的 IP 地址,我們可以繼續 DNS 請求了:
當瀏覽器得到了目標服務器的 IP 地址,以及 URL 中給出來端口號(http 協議默認端口號是 80, https 默認端口號是 443),它會調用系統庫函數 ,請求一個 TCP流套接字,對應的參數是 / 和 。
到了現在,TCP 封包已經準備好了,可以進行tcp三次握手(在地址解析完畢后首先進行的是三次握手,就是客戶端和服務器端只發送SYN包,建立三次連接后,在對HTTP的引用進行響應)
最終封包會到達管理本地子網的路由器。在那里出發,它會繼續經過自治區域( , 縮寫 AS)的邊界路由器,其他自治區域,最終到達目標服務器。一路上經過的這些路由器會從IP數據報頭部里提取出目標地址,并將封包正確地路由到下一個目的地。IP數據報頭部 time to live (TTL) 域的值每經過一個路由器就減1網頁中列表的類型有,如果封包的TTL變為0,或者路由器由于網絡擁堵等原因封包隊列滿了,那么這個包會被路由器丟棄。
8. TLS 握手9. HTTP 服務器請求處理
HTTPD(HTTP )在服務器端處理請求/響應。最常見的 HTTPD 有 Linux 上常用的 和 nginx,以及 上的 IIS。
服務器驗證其上已經配置了 的虛擬主機
服務器驗證 接受 GET 方法
服務器驗證該用戶可以使用 GET 方法(根據 IP 地址,身份信息等)
如果服務器安裝了 URL 重寫模塊(例如 的 和 IIS 的 URL ),服務器會嘗試匹配重寫規則,如果匹配上的話,服務器會按照規則重寫這個請求
服務器根據請求信息獲取相應的響應內容,這種情況下由于訪問路徑是 “/“ ,會訪問首頁文件(你可以重寫這個規則,但是這個是最常用的)。
服務器會使用指定的處理程序分析處理這個文件,假如 使用 PHP,服務器會使用 PHP 解析 index 文件,并捕獲輸出,把 PHP 的輸出結果返回給請求者
請求進入處理函數之后,如果客戶端所請求需要瀏覽的內容是一個動態的內容,那么處理函數會相應的從數據源里面取出數據,這個地方一般會有一個緩存,例如 來減小 db 的壓力,如果引入了 orm 框架的話,那么處理函數直接向 orm 框架索要數據就可以了,由 orm 框架來決定是使用內存里面的緩存還是從 db 去取數據,一般緩存都會有一個過期的時間,而 orm 框架也會在取到數據回來之后,把數據存一份在內存緩存中的。
orm 框架負責把面向對象的請求翻譯成標準的 sql 語句,然后送到后端的 db 去執行,db 這里以 mysql 為例的話,那么一條 sql 進來之后,db 本身也是有緩存的,不過 db 的緩存一般是用 sql 語言 hash 來存取的,也就是說,想要緩存能夠命中,除了查詢的字段和方法要一樣以外,查詢的參數也要完全一模一樣才能夠使用 db 本身的查詢緩存,sql 經過查詢緩存器,然后就會到達查詢分析器,在這里,db 會根據被搜索的數據表的索引建立情況,和 sql 語言本身的特點,來決定使用哪一個字段的索引,值得一提的是網頁中列表的類型有,即使一個數據表同時在多個字段建立了索引,但是對于一條 sql 語句來說,還是只能使用一個索引,所以這里就需要分析使用哪個索引效率最高了,一般來說,sql 優化在這個點上也是很重要的一個方面。
sql 由 db 返回結果集后,再由 orm 框架把結果轉換成模型對象,然后由 orm 框架進行一些邏輯處理,把準備好的數據,送到視圖層的渲染引擎去渲染,渲染引擎負責模板的管理,字段的友好顯示,也包括負責一些多國語言之類的任務。對于一條請求在 mvc 中的生命周期,在視圖層把頁面準備好后,再從動態腳本解釋器送回到 http 服務器,由 http 服務器把這些正文加上一個響應頭,封裝成一個標準的 http 響應包,再通過 tcp ip 協議,送回到客戶機瀏覽器。
10. 客戶端渲染