本文來自網易雲社區nginx
做者:劉超算法
上一節咱們講到,手機App通過了一個複雜的過程,終於拿到了電商網站的SLB的IP地址,是否是該下單了?
緩存
別忙,俗話說的好,買東西要貨比三家。大部分客戶在購物以前要看不少商品圖片,比來比去,最後好不容易纔下決心,點了下單按鈕。下單按鈕一按,就要開始創建鏈接。創建鏈接這個過程也挺複雜的,最終還要通過層層封裝,才構建出一個完整的網絡包。今天咱們就來看這個過程。服務器
客戶想要在購物網站買一件東西的時候,通常是先去詳情頁看看圖片,是否是想買的那一款。網絡
咱們部署電商應用的時候,通常會把靜態資源保存在兩個地方,一個是接入層nginx後面的varnish緩存裏面,通常是靜態頁面;對於比較大的、不常常更新的靜態圖片,會保存在對象存儲裏面。這兩個地方的靜態資源都會配置CDN,將資源下發到邊緣節點。
負載均衡
配置了CDN以後,權威DNS服務器上,會爲靜態資源設置一個CNAME別名,指向另一個域名cdn.com,返回給本地DNS服務器。網站
當本地DNS服務器拿到這個新的域名時,須要繼續解析這個新的域名。這個時候,再訪問的時候就不是原來的權威DNS服務器了,而是 cdn.com 的權威DNS服務器。這是CDN本身的權威DNS服務器。
加密
在這個服務器上,仍是會設置一個CNAME,指向另一個域名,也即CDN網絡的全局負載均衡器。cdn
本地DNS服務器去請求CDN的全局負載均衡器解析域名,全局負載均衡器會爲用戶選擇一臺合適的緩存服務器提供服務,將IP返回給客戶端,客戶端去訪問這個邊緣節點,下載資源。緩存服務器響應用戶請求,將用戶所需內容傳送到用戶終端。
對象
若是這臺緩存服務器上並無用戶想要的內容,那麼這臺服務器就要向它的上一級緩存服務器請求內容,直至追溯到網站的源服務器,將內容拉到本地。
有關CDN,請參考《CDN:你去小賣部取過快遞麼?》
當你瀏覽了不少圖片,發現實在喜歡某個商品,因而決定下單購買。
電商網站會對下單的狀況提供RESTful的下單接口,而對於下單這種須要保密的操做,須要經過HTTPS協議進行請求。
在全部這些操做以前,首先要作的事情是創建鏈接。
HTTPS協議是基於TCP協議的,於是要先創建TCP的鏈接。在這個例子中,TCP的鏈接是從手機上的App和負載均衡器SLB之間的。
儘管中間要通過不少的路由器和交換機,可是TCP的鏈接是端到端的。TCP這一層和更上層的HTTPS沒法看到中間的包的過程。儘管創建鏈接的時候,全部的包都逃不過在這些路由器和交換機之間的轉發,轉發的細節咱們放到那個下單請求的發送過程當中詳細解讀,這裏只看端到端的行爲。
對於TCP鏈接來說,須要經過三次握手創建鏈接,爲了維護這個鏈接,雙方都須要在TCP層維護一個鏈接的狀態機。
一開始,客戶端和服務端都處於CLOSED狀態。服務端先是主動監聽某個端口,處於LISTEN狀態。而後客戶端主動發起鏈接SYN,以後處於SYN-SENT狀態。服務端收到發起的鏈接,返回SYN,而且ACK客戶端的SYN,以後處於SYN-RCVD狀態。
客戶端收到服務端發送的SYN和ACK以後,發送ACK的ACK,以後處於ESTABLISHED狀態。這是由於,它一發一收成功了。服務端收到ACK的ACK以後,處於ESTABLISHED狀態,由於它的一發一收也成功了。
當TCP層的鏈接創建完畢以後,接下來輪到HTTPS層創建鏈接了,在HTTPS的交換過程當中,TCP層始終處於ESTABLISHED。
對於HTTPS,客戶端會發送Client Hello消息到服務器,用明文傳輸TLS版本信息、加密套件候選列表、壓縮算法候選列表等信息。另外,還會有一個隨機數,在協商對稱密鑰的時候使用。
而後,服務器會返回Server Hello消息,告訴客戶端,服務器選擇使用的協議版本、加密套件、壓縮算法等。這也有一個隨機數,用於後續的密鑰協商。
而後,服務器會給你一個服務器端的證書,而後說:「Server Hello Done,我這裏就這些信息了。」
客戶端固然不相信這個證書,因而你從本身信任的CA倉庫中,拿CA的證書裏面的公鑰去解密電商網站的證書。若是可以成功,則說明電商網站是可信的。這個過程當中,你可能會不斷往上追溯CA、CA的CA、CA的CA的CA,反正直到一個授信的CA,就能夠了。
證書驗證完畢以後,以爲這個服務端是可信的,因而客戶端計算產生隨機數字Pre-master,發送Client Key Exchange,用證書中的公鑰加密,再發送給服務器,服務器能夠經過私鑰解密出來。
接下來,不管是客戶端仍是服務器,都有了三個隨機數,分別是:本身的、對端的,以及剛生成的Pre-Master隨機數。經過這三個隨機數,能夠在客戶端和服務器產生相同的對稱密鑰。
有了對稱密鑰,客戶端就能夠說:「Change Cipher Spec,我們之後都採用協商的通訊密鑰和加密算法進行加密通訊了。」
而後客戶端發送一個Encrypted Handshake Message,將已經商定好的參數等,採用協商密鑰進行加密,發送給服務器用於數據與握手驗證。
一樣,服務器也能夠發送Change Cipher Spec,說:「沒問題,我們之後都採用協商的通訊密鑰和加密算法進行加密通訊了」,而且也發送Encrypted Handshake Message的消息試試。
當雙方握手結束以後,就能夠經過對稱密鑰進行加密傳輸了。
真正的下單請求封裝成網絡包的發送過程,咱們先放一放,咱們來接着講這個網絡包的故事。
有關TCP協議,參考《TCP協議(上):因性惡而複雜,先惡後善反輕鬆》和《TCP協議(下):西行一定多妖孽,恆心智慧消磨難》
有關HTTP協議,參考《HTTP協議:看個新聞原來這麼麻煩》,有關HTTPS協議參考《HTTPS協議:點外賣的過程原來這麼複雜》
有關RESTful API,參考《基於JSON的RESTful接口協議:我不關心過程,請給我結果》
當客戶端和服務端之間創建了鏈接後,接下來就要發送下單請求的網絡包了。
在用戶層發送的是HTTP的網絡包,由於服務端提供的是RESTful API,於是HTTP層發送的就是一個請求。