《web性能權威指南》第一部分閱讀筆記
1 人贊了文章
tcp:
1. 三次握手四次揮手,基本知識
2.擁塞
擁塞崩潰:「往返時間超過了所有主機的最大中斷間隔,於是相應的主機會在網路 中製造越來越多的數據報副本,使得整個網路陷入癱瘓。最終,所有交換節 點的緩衝區都將被填滿,多出來的分組必須刪掉。目前的分組往返時間已經 設定為最大值。主機會把每個分組都發送好幾次,結果每個分組的某個副本 會抵達目標。這就是擁塞崩潰」
流量控制: 首先,tcp連接的每一方都會通告自己的接受窗口(rwnd) 其中包含能夠保存數據的緩衝區空間大小信息。
如果其中一端跟不上數據傳輸,那它可以向發送端通告一個較小的窗口。 假如窗口為零,則意味著必須由應用層先清空緩衝區,才能再接收剩餘數據。這個過 程貫穿於每個 TCP 連接的整個生命周期:每個 ACK 分組都會攜帶相應的最新 rwnd 值,以便兩端動態調整數據流速,使之適應發送端和接收端的容量及處理能力
也就是說,每個ack都會攜帶rwnd的值,隨時調整數據流速。
慢啟動、擁塞預防、快速重發和快速恢復:
這四大演算法是用來進行擁塞控制的。光有流量控制還不夠,舉個例子:你在家裡觀看一個大型的流視頻。視頻 伺服器會盡最大努力根據你的下行連接提供最高品質信息。而此時,你家裡又有人 打開一個新連接下載某個軟體的升級包。可供視頻流使用的下行帶寬一下子少了很 多,視頻伺服器必須調整它的發送速度。否則,如果繼續保持同樣的速度,那麼數據很快就會在某個中間的網關越積越多,最終會導致分組被刪除,從而降低網路傳輸效率。
tcp三次握手後,伺服器與客戶端開始交換數據,為了解決以上場景,需要評估連接的可用帶寬,這也是慢啟動的設計思路。首先,伺服器通過 TCP 連接初始化一個新的擁塞窗口 (cwnd)變數,將其值設置為一個系統設定的保守值,而可傳輸的最大數據,取rwnd與cwnd的最小值。由於網路狀況一直在變化,如何確定cwnd的最優值呢?這就需要慢啟動演算法。
慢啟動演算法
之前介紹的滑動窗口能夠讓協議棧同時發送多個報文段,這樣可以提高網路通信的效率,對於一些處理能力不佳的中間路由器,很可能會導致存儲被耗盡的狀況,從而嚴重降低了TCP連接的吞吐量,不斷的重傳. 非常的可怕, 介於此,引入了慢啟動這個演算法。慢啟動為發送方的TCP增加了一個窗口:擁塞窗口,記為cwnd,,初始化之後慢慢增加這個cwnd的值來提升速度。同時也引入了ssthresh門限值,如果cwnd達到這個值會讓cwnd的增長變得平滑,演算法如下1. 連接建好的開始先初始化cwnd = 1,表明可以傳一個MSS大小的數據2. 每當收到一個ACK,cwnd++; 呈線性上升3. 每當過了一個RTT,cwnd = cwnd*2; 呈指數讓升4. 當cwnd >= ssthresh時,就會進入「擁塞避免演算法」擁塞預防演算法
慢啟動以保守的窗口初始化連接,隨後的 每次往返都會成倍提高傳輸的數據量,直到超過接收端的流量控制窗口,即系統 配置的擁塞閾值(ssthresh)窗口,或者有分組丟失為止,此時擁塞預防演算法介入 。從慢啟動可以看到,cwnd可以比較快的增長,但是不能一直無限增長,需要某個限制,TCP使用了ssthresh的變數,當cwnd超過這個值後,慢啟動過程結束,進入擁塞避免階段。擁塞避免的主要思想是加法增大,也就是讓cwnd的值線性增加,此時當窗口中所有的報文段都被確認是,cwnd的大小才加1,cwnd的值隨著RTT線性增加,這樣就可以避免增長過快導致網路擁塞,慢慢的增加到網路的最佳值。演算法:1)收到一個ACK時,cwnd = cwnd + 1/cwnd2)當每過一個RTT時,cwnd = cwnd + 1
快重傳與快恢復書中未提及
帶寬延遲積:鏈路的帶寬(單位比特每秒)與來回通信延遲(RTT,單位秒)的乘積。結果為比特的數據量,表示在特定時間該網路上的最大數據量--已發送但尚未確認的數據。
舉例:100MB/s的帶寬,另一端最優窗口為64kb大小 若ping 對端rtt為1s
64x1024x8 /1s = 64KB/s 的速度,那麼你的發包速度很快會佔滿窗口,必須等待ACK回來才能重新發包,所以你的速度大概只能有64KB/S
若rtt為1ms,那麼帶寬時延乘積為100Kb (12.5KB), 小於窗口大小,所以速度基本是線速100mb/s
如果RTT穩定為10ms,那麼理論速度為64*8/10=51.2Mb/s。
隊首阻塞:
每個TCP分組都會帶著一個唯一的序列號被發出,而所有分組必須按順序傳送到接收端。如果中途有一個分組沒能到達接收端,那麼後續分組必須保存在接收端的TCP緩衝區,等待丟失的分組重發併到達接收端。這一切都發生在TCP層,應用程序對TCP重發和緩衝區中排隊的分組一無所知,必須等待分組全部到達才能訪問數據。
udp:
udp無協議服務:無論是tcp還是udp,都是依賴ip協議的,而ip協議主要是按照地址從源主機向目標主機發送數據報,存儲了一些路由信息,所以ip協議本身並不保證消息的可靠交付,而是依賴於其上一層的協議來進行檢測、恢復、重發。
因此,udp:
不保證消息交付?
不確認,不重傳,無超時。
不保證交付順序?
不設置包序號,不重排,不會發生隊首阻塞。
不跟蹤連接狀態?
不必建立連接或重啟狀態機。
不需要擁塞控制?
不內置客戶端或網路反饋機制
udp與nat,nat穿透(TURN、STUN、 ICE等技術):
NAT設備依賴連接狀態,而 UDP沒有狀態,而發送出站UDP不費事,但路由響應卻需要轉換表中有一個條目能告訴我們本地目標主機的IP和埠。因此轉換器必須保存每個UDP流的狀態,而UDP自身卻沒有狀態。nat設備可以刪除轉換記錄,而udp不像tcp,有斷開確認等環節,因此,引入一個雙向keep-alive分組,周期性的重置nat設備上的轉換記錄計時器。
但是在p2p中有可能根本不需要建立udp連接,因此udp需要nat設備轉換內外網ip以及埠號, 客戶端(作為伺服器)處理來自 P2P 應用程序(VoIP、遊戲、文件共享的入站連接時,就必須面對NAT穿透問題.
TURN、STUN、 ICE: 後期補圖說明
tls:
TLS 協議的目標是為在它之上運行的應用提供三個基本服務:加密、身份驗證和數據完整性
tls握手:
客戶端與伺服器在通過 TLS 交換數據之前,必須協商建立加密信道。協商內容包括 TLS 版本、加密套件,必要時還會驗證證書。然而,協商過程的每一步都需要一個分組在客戶端和伺服器之間往返一次;
協商建立 TLS 安全信道是一個複雜的過程,很容易出錯。好在伺服器和瀏覽器會替我們做好這些工作,我們要做的就是提供和配置證書!每一個 TLS 連接在 TCP 握手基礎上最多還需要兩次額外的往返。這些都會增加實際交換數據之前的等待時間!如果考慮不周,通過 TLS 交付數據很可能會引入幾百甚至幾千 ms 的網路延遲。
應用層協議協商-ALPN: 理論上,網路上任意兩端都可使用自定義的協議進行通信,當然,實際操作中不可能這樣,一般採用80與443埠,因為防火牆及其他中間設備只允許80與443埠上通信。因此,需要額外的機制確定協議。
http規定了upgrade首部可以指定一個完全不同的通信協議,但是使用upgrade需要往返一次的時間,而alpn則省去了這一次的往返時間。
客戶端在 ClientHello 消息中追加一個新的 ProtocolNameList欄位,包含自己支持的應用協議;伺服器檢查 ProtocolNameList 欄位,並在 ServerHello 消息中以 rotocolName 欄位返回選中的協議。
伺服器可以從中選擇一個協議名,否則如果不支持其中的任何協議,則斷開連接。只要 TLS 握手完成、建立了加密信道並就應用協議達成一致,客戶端與伺服器就可以立即通信。
伺服器名稱指示(SNI) :
如果伺服器想在一個 IP 地址為多個站點提供服務,則需要SNI擴展,允許客戶端在握手之初就指明要連接的主機名。Web 伺服器可以檢查 SNI 主機名,選擇適當的證書,繼續完成握手。
TLS會話恢復 :
伺服器和客戶端都保留著上一次握手後協商的加密套件與密鑰,這些都可以重用。如果找到了當初會話的session id,那麼就可以進行一次簡短的握手,否則要重新啟動一次會話協商。藉助會話標識符可以節省一次往返,還可以省掉用於協商共享加密密鑰的公鑰加密計算。由於重用了之前協商過的會話數據,就可以迅速建立一個加密連接,而且同樣安全。
那麼,新的問題又誕生了,每個tls連接,都需要佔用內存,如果伺服器為所有的客戶端都保存會話緩存,面對百萬級的連接數量來說,伺服器可吃不消,這就需要會話記錄單機制(session ticket)。該機制不用伺服器保存每個客戶端的會話狀態。相反,如 果客戶端表明其支持會話記錄單,則伺服器可以在完整 TLS 握手的最後一次交換中 添加一條「新會話記錄單」(New Session Ticket)記錄,包含只有伺服器知道的安 全密鑰加密過的所有會話數據。在後續的clinethello中,將這些信息放在sessionticket擴展中,而解密的密鑰只有伺服器知道,所以這些信息,即使放在客戶端中,也是安全的。
信任鏈與證書頒發機構 :
前面講了tls的握手、會話恢復。但是建立tls連接還必須進行身份驗證,因為加密兩端可以有攻擊者存在。必須確保我們與之交談的計算機是可信任的,否則之前的工作都是徒勞。
網上搜到了一段寫的很形象,直接搬鏈接:
數字簽名中公鑰和私鑰是什麼?今天終於弄懂了證書撤銷,證書撤銷名單、在線證書狀態協議:
CRL(Certificate Revocation List,證書撤銷名單)是 RFC 5280 規定的一種檢查所 有證書狀態的簡單機制:每個證書頒發機構維護並定期發布已撤銷證書的序列號名 單。這樣,任何想驗證證書的人都可以下載撤銷名單,檢查相應證書是否榜上有名。 如果有,說明證書已經被撤銷了。
CRL 文件本身可以定期發布、每次更新時發布,或通過 HTTP 或其他文件傳輸協議 來提供訪問。這個名單同樣由證書頒發機構簽名,通常允許被緩存一定時間。實踐 中,這種機制效果很好,但也存在一些問題:CRL 名單會隨著要撤銷的證書增多而變長,每個客戶端都必須取得包含所有序列?號的完整名單; 沒有辦法立即更新剛剛被撤銷的證書序列號,比如客戶端先緩存了 CRL,之後某證書被撤銷,那到緩存過期之前,該證書將一直被視為有效。
在線證書狀態協議(OCSP) 為解決 CRL 機制的上述問題,RFC 2560 定義了 OCSP(Online Certificate Status Protocol,在線證書狀態協議),提供了一種實時檢查證書狀態的機制。與 CRL 包含 被撤銷證書的序列號不同,OCSP 支持驗證端直接查詢證書資料庫中的序列號,從 而驗證證書鏈是否有效。總之,OCSP 佔用帶寬更少,支持實時驗證。然而,沒有什麼機制是完美無缺的!實時 OCSP 查詢也帶了一些問題:證書頒發機構必須處理實時查詢;? 證書頒發機構必須確保隨時隨地可以訪問;? 客戶端在進一步協商之前阻塞 OCSP 請求;? 由於證書頒發機構知道客戶端要訪問哪個站點,因此實時 OCSP 請求可能會泄露?客戶端的隱私。
推薦閱讀:
※「蒙卦」關於學習的啟發
※讀《你要如何衡量你的人生》
※讀書筆記(20)
※烏合之眾—讀書筆記
※《精進,如何成為一個很厲害的人》 (三)
TAG:讀書筆記 |