我們一起學習了文件系統(tǒng)和磁盤 I/O 的工作原理酣倾,以及相應的性能分析和優(yōu)化方法。接下來谤专,我們將進入下一個重要模塊—— Linux 的網(wǎng)絡子系統(tǒng)躁锡。
由于網(wǎng)絡處理的流程最復雜,跟我們前面講到的進程調度置侍、中斷處理映之、內存管理以及 I/O 等都密不可分,所以蜡坊,我把網(wǎng)絡模塊作為最后一個資源模塊來講解惕医。
同 CPU、內存以及 I/O 一樣算色,網(wǎng)絡也是 Linux 系統(tǒng)最核心的功能。網(wǎng)絡是一種把不同計算機或網(wǎng)絡設備連接到一起的技術螟够,它本質上是一種進程間通信方式灾梦,特別是跨系統(tǒng)的進程間通信,必須要通過網(wǎng)絡才能進行妓笙。隨著高并發(fā)若河、分布式、云計算寞宫、微服務等技術的普及萧福,網(wǎng)絡的性能也變得越來越重要。
網(wǎng)絡模型
說到網(wǎng)絡辈赋,我想你肯定經(jīng)常提起七層負載均衡鲫忍、四層負載均衡,或者三層設備钥屈、二層設備等等悟民。那么,這里說的二層篷就、三層射亏、四層、七層又都是什么意思呢?
實際上智润,這些層都來自國際標準化組織制定的開放式系統(tǒng)互聯(lián)通信參考模型(Open System Interconnection Reference Model)及舍,簡稱為 OSI 網(wǎng)絡模型。
- 應用層窟绷,負責為應用程序提供統(tǒng)一的接口
- 表示層锯玛,負責把數(shù)據(jù)轉換成兼容接收系統(tǒng)的格式
- 會話層,負責維護計算機之間的通信連接
- 傳輸層钾麸,負責為數(shù)據(jù)加上傳輸表頭更振,形成數(shù)據(jù)包
- 網(wǎng)絡層,負責數(shù)據(jù)的路由和轉發(fā)
- 數(shù)據(jù)鏈路層饭尝,負責 MAC 尋址肯腕、錯誤偵測和改錯
- 物理層,負責在物理網(wǎng)絡中傳輸數(shù)據(jù)幀
但是 OSI 模型還是太復雜了钥平,也沒能提供一個可實現(xiàn)的方法实撒。所以,在 Linux 中涉瘾,我們實際上使用的是另一個更實用的四層模型知态,即 TCP/IP 網(wǎng)絡模型。
TCP/IP 模型立叛,把網(wǎng)絡互聯(lián)的框架分為應用層负敏、傳輸層、網(wǎng)絡層秘蛇、網(wǎng)絡接口層等四層其做,其中,
- 應用層赁还,負責向用戶提供一組應用程序妖泄,比如 HTTP、FTP艘策、DNS 等蹈胡。
- 傳輸層,負責端到端的通信朋蔫,比如 TCP罚渐、UDP 等。
- 網(wǎng)絡層驯妄,負責網(wǎng)絡包的封裝搅轿、尋址和路由,比如 IP富玷、ICMP 等璧坟。
- 網(wǎng)絡接口層既穆,負責網(wǎng)絡包在物理網(wǎng)絡中的傳輸,比如 MAC 尋址雀鹃、錯誤偵測以及通過網(wǎng)卡傳輸網(wǎng)絡幀等幻工。
為了幫你更形象理解 TCP/IP 與 OSI 模型的關系,我畫了一張圖黎茎,如下所示:
當然了囊颅,雖說 Linux 實際按照 TCP/IP 模型,實現(xiàn)了網(wǎng)絡協(xié)議棧傅瞻,但在平時的學習交流中踢代,我們習慣上還是用 OSI 七層模型來描述。比如嗅骄,說到七層和四層負載均衡胳挎,對應的分別是 OSI 模型中的應用層和傳輸層(而它們對應到 TCP/IP 模型中,實際上是四層和三層)溺森。
OSI七層和TCP/IP四層的關系
OSI引入了服務慕爬、接口、協(xié)議屏积、分層的概念医窿,TCP/IP借鑒了OSI的這些概念建立TCP/IP模型。
OSI先有模型炊林,后有協(xié)議姥卢,先有標準,后進行實踐渣聚;而TCP/IP則相反独榴,先有協(xié)議和應用再提出了模型,且是參照的OSI模型饵逐。
OSI是一種理論下的模型,而TCP/IP已被廣泛使用彪标,成為網(wǎng)絡互聯(lián)事實上的標準倍权。
Linux 網(wǎng)絡棧
有了 TCP/IP 模型后,在進行網(wǎng)絡傳輸時捞烟,數(shù)據(jù)包就會按照協(xié)議棧薄声,對上一層發(fā)來的數(shù)據(jù)進行逐層處理;然后封裝上該層的協(xié)議頭题画,再發(fā)送給下一層默辨。
當然,網(wǎng)絡包在每一層的處理邏輯苍息,都取決于各層采用的網(wǎng)絡協(xié)議缩幸。比如在應用層壹置,一個提供 REST API 的應用,可以使用 HTTP 協(xié)議表谊,把它需要傳輸?shù)?JSON 數(shù)據(jù)封裝到 HTTP 協(xié)議中钞护,然后向下傳遞給 TCP 層。
而封裝做的事情就很簡單了爆办,只是在原來的負載前后难咕,增加固定格式的元數(shù)據(jù),原始的負載數(shù)據(jù)并不會被修改距辆。
比如余佃,以通過 TCP 協(xié)議通信的網(wǎng)絡包為例,通過下面這張圖跨算,我們可以看到爆土,應用程序數(shù)據(jù)在每個層的封裝格式。
這些新增的頭部和尾部漂彤,增加了網(wǎng)絡包的大小雾消,但我們都知道,物理鏈路中并不能傳輸任意大小的數(shù)據(jù)包挫望。網(wǎng)絡接口配置的最大傳輸單元(MTU)立润,就規(guī)定了最大的 IP 包大小。在我們最常用的以太網(wǎng)中媳板,MTU 默認值是 1500(這也是 Linux 的默認值)桑腮。
一旦網(wǎng)絡包超過 MTU 的大小,就會在網(wǎng)絡層分片蛉幸,以保證分片后的 IP 包不大于 MTU 值破讨。顯然,MTU 越大奕纫,需要的分包也就越少提陶,自然,網(wǎng)絡吞吐能力就越好匹层。
理解了 TCP/IP 網(wǎng)絡模型和網(wǎng)絡包的封裝原理后隙笆,你很容易能想到,Linux 內核中的網(wǎng)絡棧升筏,其實也類似于 TCP/IP 的四層結構撑柔。如下圖所示,就是 Linux 通用 IP 網(wǎng)絡棧的示意圖:
我們從上到下來看這個網(wǎng)絡棧您访,你可以發(fā)現(xiàn)铅忿,
- 最上層的應用程序,需要通過系統(tǒng)調用灵汪,來跟套接字接口進行交互檀训;
- 套接字的下面柑潦,就是我們前面提到的傳輸層、網(wǎng)絡層和網(wǎng)絡接口層肢扯;
- 最底層妒茬,則是網(wǎng)卡驅動程序以及物理網(wǎng)卡設備。
這里我簡單說一下網(wǎng)卡蔚晨。網(wǎng)卡是發(fā)送和接收網(wǎng)絡包的基本設備乍钻。在系統(tǒng)啟動過程中,網(wǎng)卡通過內核中的網(wǎng)卡驅動程序注冊到系統(tǒng)中铭腕。而在網(wǎng)絡收發(fā)過程中银择,內核通過中斷跟網(wǎng)卡進行交互。
再結合前面提到的 Linux 網(wǎng)絡棧累舷,可以看出浩考,網(wǎng)絡包的處理非常復雜。所以被盈,網(wǎng)卡硬中斷只處理最核心的網(wǎng)卡數(shù)據(jù)讀取或發(fā)送析孽,而協(xié)議棧中的大部分邏輯,都會放到軟中斷中處理只怎。
Linux 網(wǎng)絡收發(fā)流程
我們先來看網(wǎng)絡包的接收流程袜瞬。
當一個網(wǎng)絡幀到達網(wǎng)卡后,網(wǎng)卡會通過 DMA 方式身堡,把這個網(wǎng)絡包放到收包隊列中邓尤;然后通過硬中斷,告訴中斷處理程序已經(jīng)收到了網(wǎng)絡包贴谎。
接著汞扎,網(wǎng)卡中斷處理程序會為網(wǎng)絡幀分配內核數(shù)據(jù)結構(sk_buff),并將其拷貝到 sk_buff 緩沖區(qū)中擅这;然后再通過軟中斷澈魄,通知內核收到了新的網(wǎng)絡幀。
接下來仲翎,內核協(xié)議棧從緩沖區(qū)中取出網(wǎng)絡幀痹扇,并通過網(wǎng)絡協(xié)議棧,從下到上逐層處理這個網(wǎng)絡幀谭确。比如帘营,
- 在鏈路層檢查報文的合法性票渠,找出上層協(xié)議的類型(比如 IPv4 還是 IPv6)逐哈,再去掉幀頭、幀尾问顷,然后交給網(wǎng)絡層昂秃。
- 網(wǎng)絡層取出 IP 頭禀梳,判斷網(wǎng)絡包下一步的走向,比如是交給上層處理還是轉發(fā)肠骆。當網(wǎng)絡層確認這個包是要發(fā)送到本機后算途,就會取出上層協(xié)議的類型(比如 TCP 還是 UDP),去掉 IP 頭蚀腿,再交給傳輸層處理嘴瓤。
- 傳輸層取出 TCP 頭或者 UDP 頭后,根據(jù) < 源 IP莉钙、源端口廓脆、目的 IP、目的端口 > 四元組作為標識磁玉,找出對應的 Socket停忿,并把數(shù)據(jù)拷貝到 Socket 的接收緩存中。
最后蚊伞,應用程序就可以使用 Socket 接口席赂,讀取到新接收到的數(shù)據(jù)了。
為了更清晰表示這個流程时迫,我畫了一張圖颅停,這張圖的左半部分表示接收流程,而圖中的粉色箭頭則表示網(wǎng)絡包的處理路徑别垮。
網(wǎng)絡包的發(fā)送流程
了解網(wǎng)絡包的接收流程后便监,就很容易理解網(wǎng)絡包的發(fā)送流程。網(wǎng)絡包的發(fā)送流程就是上圖的右半部分碳想,很容易發(fā)現(xiàn)烧董,網(wǎng)絡包的發(fā)送方向,正好跟接收方向相反胧奔。
首先逊移,應用程序調用 Socket API(比如 sendmsg)發(fā)送網(wǎng)絡包。
由于這是一個系統(tǒng)調用龙填,所以會陷入到內核態(tài)的套接字層中胳泉。套接字層會把數(shù)據(jù)包放到 Socket 發(fā)送緩沖區(qū)中。
接下來岩遗,網(wǎng)絡協(xié)議棧從 Socket 發(fā)送緩沖區(qū)中扇商,取出數(shù)據(jù)包;再按照 TCP/IP 棧宿礁,從上到下逐層處理案铺。比如,傳輸層和網(wǎng)絡層梆靖,分別為其增加 TCP 頭和 IP 頭控汉,執(zhí)行路由查找確認下一跳的 IP笔诵,并按照 MTU 大小進行分片。
分片后的網(wǎng)絡包姑子,再送到網(wǎng)絡接口層乎婿,進行物理地址尋址,以找到下一跳的 MAC 地址街佑。然后添加幀頭和幀尾谢翎,放到發(fā)包隊列中。這一切完成后沐旨,會有軟中斷通知驅動程序:發(fā)包隊列中有新的網(wǎng)絡幀需要發(fā)送岳服。
最后,驅動程序通過 DMA 希俩,從發(fā)包隊列中讀出網(wǎng)絡幀吊宋,并通過物理網(wǎng)卡把它發(fā)送出去。
小結
多臺服務器通過網(wǎng)卡颜武、交換機璃搜、路由器等網(wǎng)絡設備連接到一起,構成了相互連接的網(wǎng)絡鳞上。由于網(wǎng)絡設備的異構性和網(wǎng)絡協(xié)議的復雜性环戈,國際標準化組織定義了一個七層的 OSI 網(wǎng)絡模型曲管,但是這個模型過于復雜转培,實際工作中的事實標準诚啃,是更為實用的 TCP/IP 模型。
TCP/IP 模型鬼贱,把網(wǎng)絡互聯(lián)的框架移怯,分為應用層、傳輸層这难、網(wǎng)絡層舟误、網(wǎng)絡接口層等四層,這也是 Linux 網(wǎng)絡棧最核心的構成部分姻乓。
- 應用程序通過套接字接口發(fā)送數(shù)據(jù)包嵌溢,先要在網(wǎng)絡協(xié)議棧中從上到下進行逐層處理,最終再送到網(wǎng)卡發(fā)送出去蹋岩。
- 而接收時赖草,同樣先經(jīng)過網(wǎng)絡棧從下到上的逐層處理,最終才會送到應用程序剪个。
FAQ
我結合網(wǎng)絡上查閱的資料和文章中的內容秧骑,總結了下網(wǎng)卡收發(fā)報文的過程,不知道是否正確:
- 內核分配一個主內存地址段(DMA緩沖區(qū)),網(wǎng)卡設備可以在DMA緩沖區(qū)中讀寫數(shù)據(jù)(應該是網(wǎng)絡包到了之后腿堤,才分配DMA緩沖區(qū)
) - 當來了一個網(wǎng)絡包,網(wǎng)卡將網(wǎng)絡包寫入DMA緩沖區(qū)如暖,寫完后通知CPU產(chǎn)生硬中斷
- 硬中斷處理程序鎖定當前DMA緩沖區(qū)笆檀,然后將網(wǎng)絡包拷貝到另一塊內存區(qū),清空并解鎖當前DMA緩沖區(qū)盒至,然后通知軟中斷去處理網(wǎng)絡包酗洒。
當發(fā)送數(shù)據(jù)包時,與上述相反枷遂。鏈路層將數(shù)據(jù)包封裝完畢后樱衷,放入網(wǎng)卡的DMA緩沖區(qū),并調用系統(tǒng)硬中斷酒唉,通知網(wǎng)卡從緩沖區(qū)讀取并發(fā)送數(shù)據(jù)矩桂。
了解 Linux 網(wǎng)絡的基本原理和收發(fā)流程后,你肯定迫不及待想知道痪伦,如何去觀察網(wǎng)絡的性能情況侄榴。具體而言,哪些指標可以用來衡量 Linux 的網(wǎng)絡性能呢网沾?
性能指標
實際上癞蚕,我們通常用帶寬、吞吐量辉哥、延時桦山、PPS(Packet Per Second)等指標衡量網(wǎng)絡的性能。
- 帶寬醋旦,表示鏈路的最大傳輸速率恒水,單位通常為 b/s (比特 / 秒)
- 吞吐量,表示單位時間內成功傳輸?shù)臄?shù)據(jù)量饲齐,單位通常為 b/s(比特 / 秒)或者 B/s(字節(jié) / 秒)寇窑。吞吐量受帶寬限制,而吞吐量 / 帶寬箩张,也就是該網(wǎng)絡的使用率甩骏。
- 延時,表示從網(wǎng)絡請求發(fā)出后先慷,一直到收到遠端響應饮笛,所需要的時間延遲。在不同場景中论熙,這一指標可能會有不同含義福青。比如,它可以表示,建立連接需要的時間(比如 TCP 握手延時)无午,或一個數(shù)據(jù)包往返所需的時間(比如 RTT)媒役。
- PPS,是 Packet Per Second(包 / 秒)的縮寫宪迟,表示以網(wǎng)絡包為單位的傳輸速率酣衷。PPS 通常用來評估網(wǎng)絡的轉發(fā)能力,比如硬件交換機次泽,通炒┮牵可以達到線性轉發(fā)(即 PPS 可以達到或者接近理論最大值)。而基于 Linux 服務器的轉發(fā)意荤,則容易受網(wǎng)絡包大小的影響啊片。
除了這些指標,網(wǎng)絡的可用性(網(wǎng)絡能否正常通信)玖像、并發(fā)連接數(shù)(TCP 連接數(shù)量)紫谷、丟包率(丟包百分比)、重傳率(重新傳輸?shù)木W(wǎng)絡包比例)等也是常用的性能指標捐寥。
網(wǎng)絡配置
分析網(wǎng)絡問題的第一步碴里,通常是查看網(wǎng)絡接口的配置和狀態(tài)。你可以使用 ifconfig 或者 ip 命令上真,來查看網(wǎng)絡的配置咬腋。我個人更推薦使用 ip 工具,因為它提供了更豐富的功能和更易用的接口睡互。
ifconfig 和 ip 分別屬于軟件包 net-tools 和 iproute2根竿,iproute2 是 net-tools 的下一代。通常情況下它們會在發(fā)行版中默認安裝就珠。但如果你找不到 ifconfig 或者 ip 命令寇壳,可以安裝這兩個軟件包。
以網(wǎng)絡接口 eth0 為例妻怎,你可以運行下面的兩個命令壳炎,查看它的配置和狀態(tài):
$ ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.240.0.30 netmask 255.240.0.0 broadcast 10.255.255.255
inet6 fe80::20d:3aff:fe07:cf2a prefixlen 64 scopeid 0x20<link>
ether 78:0d:3a:07:cf:3a txqueuelen 1000 (Ethernet)
RX packets 40809142 bytes 9542369803 (9.5 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 32637401 bytes 4815573306 (4.8 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
?
$ ip -s addr show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 78:0d:3a:07:cf:3a brd ff:ff:ff:ff:ff:ff
inet 10.240.0.30/12 brd 10.255.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20d:3aff:fe07:cf2a/64 scope link
valid_lft forever preferred_lft forever
RX: bytes packets errors dropped overrun mcast
9542432350 40809397 0 0 0 193
TX: bytes packets errors dropped carrier collsns
4815625265 32637658 0 0 0 0
你可以看到,ifconfig 和 ip 命令輸出的指標基本相同逼侦,只是顯示格式略微不同匿辩。比如,它們都包括了網(wǎng)絡接口的狀態(tài)標志榛丢、MTU 大小铲球、IP、子網(wǎng)晰赞、MAC 地址以及網(wǎng)絡包收發(fā)的統(tǒng)計信息稼病。
第一选侨,網(wǎng)絡接口的狀態(tài)標志。ifconfig 輸出中的 RUNNING 然走,或 ip 輸出中的 LOWER_UP 援制,都表示物理網(wǎng)絡是連通的,即網(wǎng)卡已經(jīng)連接到了交換機或者路由器中芍瑞。如果你看不到它們晨仑,通常表示網(wǎng)線被拔掉了。
第二啄巧,MTU 的大小。MTU 默認大小是 1500掌栅,根據(jù)網(wǎng)絡架構的不同(比如是否使用了 VXLAN 等疊加網(wǎng)絡)秩仆,你可能需要調大或者調小 MTU 的數(shù)值。
第三猾封,網(wǎng)絡接口的 IP 地址澄耍、子網(wǎng)以及 MAC 地址。這些都是保障網(wǎng)絡功能正常工作所必需的晌缘,你需要確保配置正確齐莲。
第四,網(wǎng)絡收發(fā)的字節(jié)數(shù)磷箕、包數(shù)选酗、錯誤數(shù)以及丟包情況,特別是 TX 和 RX 部分的 errors岳枷、dropped芒填、overruns、carrier 以及 collisions 等指標不為 0 時空繁,通常表示出現(xiàn)了網(wǎng)絡 I/O 問題殿衰。其中:
- errors 表示發(fā)生錯誤的數(shù)據(jù)包數(shù),比如校驗錯誤盛泡、幀同步錯誤等闷祥;
- dropped 表示丟棄的數(shù)據(jù)包數(shù),即數(shù)據(jù)包已經(jīng)收到了 Ring Buffer傲诵,但因為內存不足等原因丟包凯砍;
- overruns 表示超限數(shù)據(jù)包數(shù),即網(wǎng)絡 I/O 速度過快拴竹,導致 Ring Buffer 中的數(shù)據(jù)包來不及處理(隊列滿)而導致的丟包果覆;
- carrier 表示發(fā)生 carrirer 錯誤的數(shù)據(jù)包數(shù),比如雙工模式不匹配殖熟、物理電纜出現(xiàn)問題等局待;
- collisions 表示碰撞數(shù)據(jù)包數(shù)。
套接字信息
ifconfig 和 ip 只顯示了網(wǎng)絡接口收發(fā)數(shù)據(jù)包的統(tǒng)計信息,但在實際的性能問題中钳榨,網(wǎng)絡協(xié)議棧中的統(tǒng)計信息舰罚,我們也必須關注。你可以用 netstat 或者 ss 薛耻,來查看套接字营罢、網(wǎng)絡棧、網(wǎng)絡接口以及路由表的信息饼齿。
我個人更推薦饲漾,使用 ss 來查詢網(wǎng)絡的連接信息,因為它比 netstat 提供了更好的性能(速度更快)缕溉。
比如考传,你可以執(zhí)行下面的命令,查詢套接字信息:
# head -n 3 表示只顯示前面3行
# -l 表示只顯示監(jiān)聽套接字
# -n 表示顯示數(shù)字地址和端口(而不是名字)
# -p 表示顯示進程信息
$ netstat -nlp | head -n 3
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 840/systemd-resolve
# -l 表示只顯示監(jiān)聽套接字
# -t 表示只顯示 TCP 套接字
# -n 表示顯示數(shù)字地址和端口(而不是名字)
# -p 表示顯示進程信息
$ ss -ltnp | head -n 3
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=840,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1459,fd=3))
netstat 和 ss 的輸出也是類似的证鸥,都展示了套接字的狀態(tài)僚楞、接收隊列、發(fā)送隊列枉层、本地地址泉褐、遠端地址、進程 PID 和進程名稱等鸟蜡。
其中膜赃,接收隊列(Recv-Q)和發(fā)送隊列(Send-Q)需要你特別關注,它們通常應該是 0揉忘。當你發(fā)現(xiàn)它們不是 0 時财剖,說明有網(wǎng)絡包的堆積發(fā)生。當然還要注意癌淮,在不同套接字狀態(tài)下躺坟,它們的含義不同。
當套接字處于連接狀態(tài)(Established)時乳蓄,
- Recv-Q 表示套接字緩沖還沒有被應用程序取走的字節(jié)數(shù)(即接收隊列長度)咪橙。
- 而 Send-Q 表示還沒有被遠端主機確認的字節(jié)數(shù)(即發(fā)送隊列長度)。
當套接字處于監(jiān)聽狀態(tài)(Listening)時虚倒,
- Recv-Q 表示全連接隊列的長度美侦。
- 而 Send-Q 表示全連接隊列的最大長度。
所謂全連接魂奥,是指服務器收到了客戶端的 ACK菠剩,完成了 TCP 三次握手,然后就會把這個連接挪到全連接隊列中耻煤。這些全連接中的套接字具壮,還需要被 accept() 系統(tǒng)調用取走准颓,服務器才可以開始真正處理客戶端的請求。
與全連接隊列相對應的棺妓,還有一個半連接隊列攘已。所謂半連接是指還沒有完成 TCP 三次握手的連接,連接只進行了一半怜跑。服務器收到了客戶端的 SYN 包后样勃,就會把這個連接放到半連接隊列中,然后再向客戶端發(fā)送 SYN+ACK 包性芬。
協(xié)議棧統(tǒng)計信息
類似的峡眶,使用 netstat 或 ss ,也可以查看協(xié)議棧的信息:
$ netstat -s
...
Tcp:
3244906 active connection openings
23143 passive connection openings
115732 failed connection attempts
2964 connection resets received
1 connections established
13025010 segments received
17606946 segments sent out
44438 segments retransmitted
42 bad segments received
5315 resets sent
InCsumErrors: 42
...
$ ss -s
Total: 186 (kernel 1446)
TCP: 4 (estab 1, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0
Transport Total IP IPv6
* 1446 - -
RAW 2 1 1
UDP 2 2 0
TCP 4 3 1
...
這些協(xié)議棧的統(tǒng)計信息都很直觀植锉。ss 只顯示已經(jīng)連接辫樱、關閉、孤兒套接字等簡要統(tǒng)計汽煮,而 netstat 則提供的是更詳細的網(wǎng)絡協(xié)議棧信息搏熄。
比如棚唆,上面 netstat 的輸出示例暇赤,就展示了 TCP 協(xié)議的主動連接、被動連接宵凌、失敗重試鞋囊、發(fā)送和接收的分段數(shù)量等各種信息。
網(wǎng)絡吞吐和 PPS
接下來瞎惫,我們再來看看溜腐,如何查看系統(tǒng)當前的網(wǎng)絡吞吐量和 PPS。在這里瓜喇,我推薦使用我們的老朋友 sar挺益,在前面的 CPU、內存和 I/O 模塊中乘寒,我們已經(jīng)多次用到它望众。
給 sar 增加 -n 參數(shù)就可以查看網(wǎng)絡的統(tǒng)計信息,比如網(wǎng)絡接口(DEV)伞辛、網(wǎng)絡接口錯誤(EDEV)烂翰、TCP、UDP蚤氏、ICMP 等等甘耿。執(zhí)行下面的命令,你就可以得到網(wǎng)絡接口統(tǒng)計信息:
# 數(shù)字1表示每隔1秒輸出一組數(shù)據(jù)
$ sar -n DEV 1
Linux 4.15.0-1035-azure (ubuntu) 01/06/19 _x86_64_ (2 CPU)
13:21:40 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
13:21:41 eth0 18.00 20.00 5.79 4.25 0.00 0.00 0.00 0.00
13:21:41 docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
13:21:41 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
這兒輸出的指標比較多竿滨,我來簡單解釋下它們的含義佳恬。
- rxpck/s 和 txpck/s 分別是接收和發(fā)送的 PPS捏境,單位為包 / 秒
- rxkB/s 和 txkB/s 分別是接收和發(fā)送的吞吐量,單位是 KB/ 秒
- rxcmp/s 和 txcmp/s 分別是接收和發(fā)送的壓縮數(shù)據(jù)包數(shù)殿怜,單位是包 / 秒
- %ifutil 是網(wǎng)絡接口的使用率典蝌,即半雙工模式下為 (rxkB/s+txkB/s)/Bandwidth,而全雙工模式下為 max(rxkB/s, txkB/s)/Bandwidth
其中头谜,Bandwidth 可以用 ethtool 來查詢骏掀,它的單位通常是 Gb/s 或者 Mb/s,不過注意這里小寫字母 b 柱告,表示比特而不是字節(jié)截驮。我們通常提到的千兆網(wǎng)卡、萬兆網(wǎng)卡等际度,單位也都是比特葵袭。如下你可以看到,我的 eth0 網(wǎng)卡就是一個千兆網(wǎng)卡:
其中乖菱,Bandwidth 可以用 ethtool 來查詢坡锡,它的單位通常是 Gb/s 或者 Mb/s,不過注意這里小寫字母 b 窒所,表示比特而不是字節(jié)鹉勒。我們通常提到的千兆網(wǎng)卡、萬兆網(wǎng)卡等吵取,單位也都是比特禽额。如下你可以看到,我的 eth0 網(wǎng)卡就是一個千兆網(wǎng)卡:
$ ethtool eth0 | grep Speed
Speed: 1000Mb/s
小結
我們通常使用帶寬皮官、吞吐量脯倒、延時等指標,來衡量網(wǎng)絡的性能捺氢;相應的藻丢,你可以用 ifconfig、netstat摄乒、ss悠反、sar、ping 等工具缺狠,來查看這些網(wǎng)絡的性能指標问慎。
小狗同學問到: 老師,您好 ss —lntp 這個 當session處于listening中 rec-q 確定是 syn的backlog嗎挤茄?
A: Recv-Q為全連接隊列當前使用了多少如叼。 中文資料里這個問題講得最明白的文章:https://mp.weixin.qq.com/s/yH3PzGEFopbpA-jw4MythQ
看了源碼發(fā)現(xiàn),這個地方講的有問題.關于ss輸出中l(wèi)isten狀態(tài)套接字的Recv-Q表示全連接隊列當前使用了多少,也就是全連接隊列的當前長度,而Send-Q表示全連接隊列的最大長度