1. 程式人生 > >計算機揭祕之:網路分類和效能分析

計算機揭祕之:網路分類和效能分析

[toc] # 簡介 程式設計師天天都在寫程式碼,關注的都是更高層次的封裝,今天我們換個思路,讓程式那些事來帶你看一看隱藏在表象之下的網路和他們的效能分析。 本文主要涉及5個模組,分別是網路七層協議,延遲與頻寬,IP,TCP,UDP。 # OSI網路七層協議 在講網路之前,一定要提到OSI網路七層協議。 OSI是Open System Interconnect的縮寫,意為開放式系統互聯。 ![](https://img-blog.csdnimg.cn/20200617103233957.png) 上圖是大家非常非常熟悉的OSI七層網路模型,和對應的TCP/IP模型。 應用層的功能是檔案傳輸,電子郵件和檔案服務等。使用的協議主要是HTTP,SMTP和FTP。 表示層的功能是資料格式化,程式碼轉換和資料加密。 會話層的功能是解除或者建立與其他節點的聯絡。 傳輸層的功能是提供端對端的介面,使用的協議主要是TCP和UDP。 網路層的功能是為資料包選擇路由,使用的協議是IP。 資料鏈路層的功能是傳輸有地址的幀,和檢查資料錯誤。 物理層的功能是以二進位制資料在物理媒介上傳輸資料。 # 延遲與頻寬 最近電信業務員老是給我打電話,說是要把家裡的電信寬頻從100M升級到500M,每天只需要一塊錢。一塊錢雖然少,但也是血汗錢。那麼辦還是不辦呢?升級到500M對效能和延時提升有多大幫助呢? 2020年可以稱為中國5G的元年。先不管華為,中信在5G基站和協議制定方面的能力。直觀的感覺5G手機開始多了,手機營業廳也在賣力的讓你升級到5G套餐,那麼辦還是不辦? 在回答這兩個問題之前,我們學習兩個名詞: 延遲: 分組從資訊源傳送到目的地所需的時間。 頻寬: 邏輯或物理通訊路徑最大的吞吐量。 ![](https://img-blog.csdnimg.cn/20200617111917272.png) 如果你訪問一個網站,比如www.flydean.com,我們看一下資料是怎麼從伺服器到達你的電腦的。 首先資料從伺服器通過乙太網(乙太網是一種計算機區域網技術)傳輸到ISP。 ISP是啥呢?ISP就是網際網路服務提供商(Internet Service Provider),通過ISP你才能夠把伺服器接入網際網路。 網際網路就是通過主幹網的網際網路服務提供商(ISP)之間的相互連線構成的。 所以ISP就是一個......大代理。 好了,資料傳到為我家提供服務的ISP了,然後通過光纖或者電纜線傳到了我家的WiFi,然後通過WiFi的無線訊號,被我的電腦接收。 ## 延時的構成 討論分析了資料的傳輸線路,接下來我們看一下,延時會跟哪些原因有關呢? 首先肯定是訊號傳輸的距離,距離越長,傳輸速率越慢,需要的時間就越長。 接下來就是訊息的長度,我們把訊息中的所有位元轉移到鏈路中需要時間,訊息長度越長,需要的時間越多。 資料上了鏈路之後,處理分組首部、檢查位錯誤及確定分組目標也需要時間。 最後,我們對於分組資料進行排隊處理也需要時間。 現在主網路的傳輸介質基本上都是光纖了,光在光纖中傳播,並不是直線進行的,並且也有折射率的影響,所以速度比光在真空中傳播要慢一點。 比如說訊號圍繞赤道轉一圈,只需要大概200ms。已經很快了。 200ms確實很快了,但是對於某些實時性要求特別高的應用場景,我們可以使用CDN技術(Content Delivery Network,內容分發網路),把內容部署在全球網路中,然後從最近的地方去取資料。從而大大減少傳輸延時。 200ms夠快了,但是為什麼我們仍然會感覺到網速慢呢? 大家都聽過木桶原理吧,木桶能夠裝的水,決定於最短的那塊木板。同樣的對於網路延時來說,提升速度不在於你在主幹網上採用了多麼先進的技術,因為提升的再多或者再差也是毫米級的。 真正決定網速的在於最後一公里,也就是你電纜線的傳輸速率,你的wifi的傳輸速率,還有你電腦的處理速率等。  能接入更高頻寬固然好,特別是傳輸大塊資料時更是如此,比如線上聽音樂、看視訊,或者下載大檔案。可是,日常上網瀏覽需要的是從數十臺主機獲取較小的資源,這時候往返時間就成了瓶頸。 # IP協議 IP,即 Internet Protocol(因特網協議),負責聯網主機之間的路由選擇和定址。 各種物理網路在鏈路層所傳輸的基本單元為幀(MAC幀),其幀格式隨物理網路而異,各物理網路的實體地址(MAC地址)也隨物理網路而異。Ip協議的作用就是向傳輸層(TCP層)提供統一的IP包,即將各種不同型別的MAC幀轉換為統一的IP包,並將MAC幀的實體地址變換為全網統一的邏輯地址(IP地址)。 ## IP資料包 資料包(data packet)是什麼? 資料包也是分組交換的一種形式,就是把所傳送的資料分段打成包,再傳送出去. 每個資料包都有報頭和報文這兩個部分,報頭中有目的地址等必要內容,使每個資料包不經過同樣的路徑都能準確地到達目的地。在目的地重新組合還原成原來發送的資料. ![](https://img-blog.csdnimg.cn/20200617122002325.png) 我們看下IP資料包的構成。 注意上面的Total Length部分佔用了2個位元組,所以IP資料包的最大長度就是2^16-1=65535位元組。 ## 分片和重組 鏈路層具有最大傳輸單元MTU這個特性,它限制了資料幀的最大長度,不同的網路型別都有一個上限值.如果IP層有資料包要傳,而且資料包的長度超過了MTU,那麼IP層就要對資料包進行分片操作,使每一片的長度都小於或等於MTU。 分片後的IP資料包,只有到達目的地才能重新組裝。重新組裝由目的地的IP層來完成,其目的是使分片和重新組裝過程對傳輸層(TCP和UDP)是透明的。 ## MSS與MTU MSS最大傳輸大小的縮寫,是TCP協議裡面的一個概念。 MSS就是TCP資料包每次能夠傳輸的最大資料分段。為了達到最佳的傳輸效能TCP協議在建立連線的時候通常要協商雙方的MSS值,這個值TCP協議在實現的時候往往用MTU值代替(需要減去IP資料包包頭的大小20Bytes和TCP資料段的包頭20Bytes), 通訊雙方會根據雙方提供的MSS值得最小值確定為這次連線的最大MSS值。 而一般乙太網MTU都為1500, 所以在乙太網中, 往往TCP MSS為1460。 # TCP  TCP,即 Transmission Control Protocol(傳輸控制協議),負責在不可靠的傳輸通道之上提供可靠的抽象層,  嚮應用層隱藏了大多數網路通訊的複雜細節,比如丟包重發、按序傳送、擁塞控制及避免、資料完整,等等。 ## TCP三次握手 ![](https://img-blog.csdnimg.cn/20200617123103697.png) 一般來說,使用TCP協議,如果client和server要達成一致建立連線的話,需要三次互動。 * SYN 客戶端選擇一個隨機序列號x,併發送一個SYN 分組,其中可能還包括其他TCP標誌和選項。 * SYN ACK 伺服器給x 加1,並選擇自己的一個隨機序列號y,追加自己的標誌和選項,然後返回響應。 * ACK 客戶端給x 和y 加1 併發送握手期間的最後一個ACK 分組。 ## 擁塞崩潰 如果幾個IP分組同時到達路由器,並期望經同一個輸出埠轉發. 顯然,不是所有分組可以同時接受處理,必須有一個服務順序,中間節點上的快取為等候服務的分組提供一定保護。 然而,如果此狀況具有一定的持續性,當快取空間被耗盡時,路由器只有丟棄分組。 在這種持續過載的狀態下,網路效能會急劇下降. ## 流量控制 流量控制是一種預防傳送端過多向接收端傳送資料的機制。否則,接收端可能因為忙碌、負載重或緩衝區既定而無法處理。 為實現流量控制,TCP連線的每一方都要通告自己的接收視窗receive window(rwnd),其中包含能夠儲存資料的緩衝區空間大小資訊。 ![](https://img-blog.csdnimg.cn/20200617122608296.png) 最初的TCP規範分配給通告視窗大小的欄位是16位的,這相當於設定了傳送端和接收端視窗的最大值(65535位元組)。結果,在這個限制內經常無法獲得最優效能。 為解決這個問題,RFC1323提供了TCP視窗縮放(TCP Window Scaling)選項,可以把接收視窗大小由65535位元組提高到1G位元組。 那麼現在問題來了,rwnd只是一個接收端的初始視窗大小,如果有多個sender都在向receiver傳送資料包的話,怎麼才能保證receiver端的接收效能呢? 為了解決這個問題,TCP引入了慢啟動的概念。 當sender和receiver已經建立好了TCP三次握手之後。就可以開始傳送資料包了。 這裡引入了一個擁堵視窗Congestion window(cwnd)的概念。 cwnd是server端目前可以接受的最大的視窗大小。 建立連線之後第一次傳送的cwnd是一個初始值,這個初始值最開始是1個network segment,在1999年 RFC 2581將其更新為4個network segments。在2013年, RFC 6928 將這個值擴大到了10個network segments。 我們以10個network segments為例,看下cwnd的膨脹過程: ![](https://img-blog.csdnimg.cn/20200617144008858.png) 一般來說cwnd是倍數增加的,收到ack之後,cwnd會從10,20,40這樣往上增加。一直到server端拒絕ack為止。 那麼回到我們之前講到的一個結論,頻寬其實不是那麼重要。 為什麼呢?考慮在HTTP1.1中,client需要等待server的返回才能夠進行下一次請求。如果你的請求的檔案比較小,那麼cwnd還沒有漲到足夠大的時候,請求就已經結束了。這個時候最主要的時間花費是請求的來回時間,而不在於頻寬大小。 當然,如果在HTTP2中,因為建立的是長連線,慢啟動可能就不存在了(不確定,大家有不同的意見可以提出)。 # UDP UDP( User Datagram Protocol,使用者資料報協議。 UDP 的主要功能和亮點並不在於它引入了什麼特性,而在於它忽略的那些特性:不保證訊息交付,不保證交付順序,不跟蹤連線狀態,不需要擁塞控制。 我們先來看一下UDP的資料包: ![](https://img-blog.csdnimg.cn/20200617170251803.png) # NAT 大家都知道IPV4地址是有限的,很快IPV4地址就快用完了,那怎麼解決這個問題呢? 當然,一個永久解決的辦法是IPV6,不過IPV6推出這麼多年了,好像還沒有真正的普及。 不使用IPV6的話還有什麼解決辦法呢? 這個辦法就是NAT(Network Address Translators)。 ![](https://img-blog.csdnimg.cn/20200617171736331.png) NAT的原理是將區域網的IP和埠和NAT裝置的IP和埠做個對映。 NAT內部維護著一張轉換表。這樣就可以通過一個NAT的IP地址和不同的埠來連線眾多的區域網伺服器。 那麼NAT有什麼問題呢? NAT的問題在於,內部客戶端不知道自己外網IP地址,只知道內網IP地址。 如果是在UDP協議中,因為UDP是無狀態的,所以需要NAT來重寫每個UDP分組中的源埠、地址,以及IP分組中的源IP地址。 如果客戶端是在應用程式內部將自己的IP地址告訴伺服器,並想跟伺服器建立連線,那麼肯定是建立不了的。因為找不到客戶端的公網IP。 即使找到了公網IP,任何到達NAT裝置外網IP的分組還必須有一個目標埠,而且NAT轉換表中也要有一個條目可以將其轉換為內部主機的IP地址和埠號。否則就可能出現下圖的連線失敗的問題。 ![](https://img-blog.csdnimg.cn/2020061717421463.png) 怎麼解決呢? 第一種方式是使用STUN伺服器。 ![](https://img-blog.csdnimg.cn/20200617175249237.png) STUN伺服器是IP地址已知的伺服器,客戶端要通訊之前,先去STUN伺服器上面查詢一下自己的外網IP和埠,然後再使用這個外網IP和埠進行通訊。 但有時UDP包會被防火牆或者其他的應用程式所阻擋。這個時候就可以使用中繼器技術Traversal Using Relays around NAT (TURN) 。 ![](https://img-blog.csdnimg.cn/20200617175739225.png) 雙方都將資料傳送到中繼器server,由中繼器server來負責轉發資料。注意,這裡已經不是P2P了。 最後,我們有一個集大成者的協議叫做ICE(Interactive Connectivity Establishment ): ![](https://img-blog.csdnimg.cn/20200617180143971.png) 它實際上就是直連,STUN和TURN的綜合體,能直連的時候就直連,不能直連就用STUN,不能用STUN就用TURN。 # 總結 本文介紹了IP,TCP和UDP等協議和需要注意的一些事項,希望大家能夠喜歡。 > 本文連結:[http://www.flydean.com/network-and-performance/](http://www.flydean.com/network-and-performance/) > > 最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現! > > 歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你! ![](https://img-blog.csdnimg.cn/20200709152618916.png)