同 CPU、內(nèi)存以及 I/O 一樣,網(wǎng)絡(luò)也是 Linux 系統(tǒng)最核心的功能。 網(wǎng)絡(luò)是一種把不同計(jì)算機(jī)或網(wǎng)絡(luò)設(shè)備連接到一起的技術(shù),它本質(zhì)上是一種進(jìn)程間通信方式,特別是跨系統(tǒng)的進(jìn)程間通信,必須要通過(guò)網(wǎng)絡(luò)才能進(jìn)行。
1 網(wǎng)絡(luò)模型
多臺(tái)服務(wù)器通過(guò)網(wǎng)卡、交換機(jī)、路由器等網(wǎng)絡(luò)設(shè)備連接到一起,構(gòu)成了相互連接的網(wǎng)絡(luò)。 由于網(wǎng)絡(luò)設(shè)備的異構(gòu)性和網(wǎng)絡(luò)協(xié)議的復(fù)雜性,國(guó)際標(biāo)準(zhǔn)化組織定義了一個(gè)七層的 OSI 網(wǎng)絡(luò)模型,但是這個(gè)模型過(guò)于復(fù)雜,實(shí)際工作中的事實(shí)標(biāo)準(zhǔn),是更為實(shí)用的 TCP/IP 模型。
在計(jì)算機(jī)網(wǎng)絡(luò)時(shí)代初期,各大廠(chǎng)商推出了不同的網(wǎng)絡(luò)架構(gòu)和標(biāo)準(zhǔn),為統(tǒng)一標(biāo)準(zhǔn),國(guó)際標(biāo)準(zhǔn)化組織 ISO 推出了統(tǒng)一的 OSI開(kāi)放式系統(tǒng)互聯(lián)通信參考模型(Open System Interconnection Reference Model)。
網(wǎng)絡(luò)分層解決了網(wǎng)絡(luò)復(fù)雜的問(wèn)題,在網(wǎng)絡(luò)中傳輸數(shù)據(jù)中,我們對(duì)不同設(shè)備之間的傳輸數(shù)據(jù)的格式,需要定義一個(gè)數(shù)據(jù)標(biāo)準(zhǔn),所以就有了網(wǎng)絡(luò)協(xié)議。
為了解決網(wǎng)絡(luò)互聯(lián)中異構(gòu)設(shè)備的兼容性問(wèn)題,并解耦復(fù)雜的網(wǎng)絡(luò)包處理流程,OSI 模型把網(wǎng)絡(luò)互聯(lián)的框架分為應(yīng)用層、表示層、會(huì)話(huà)層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層以及物理層等七層,每個(gè)層負(fù)責(zé)不同的功能。其中,
?應(yīng)用層,負(fù)責(zé)為應(yīng)用程序提供統(tǒng)一的接口。
?表示層,負(fù)責(zé)把數(shù)據(jù)轉(zhuǎn)換成兼容接收系統(tǒng)的格式。
?會(huì)話(huà)層,負(fù)責(zé)維護(hù)計(jì)算機(jī)之間的通信連接。
?傳輸層,負(fù)責(zé)為數(shù)據(jù)加上傳輸表頭,形成數(shù)據(jù)包。
?網(wǎng)絡(luò)層,負(fù)責(zé)數(shù)據(jù)的路由和轉(zhuǎn)發(fā)。
?數(shù)據(jù)鏈路層,負(fù)責(zé) MAC 尋址、錯(cuò)誤偵測(cè)和改錯(cuò)。
?物理層,負(fù)責(zé)在物理網(wǎng)絡(luò)中傳輸數(shù)據(jù)幀。
但是 OSI 模型還是太復(fù)雜了,也沒(méi)能提供一個(gè)可實(shí)現(xiàn)的方法。所以,在 Linux 中,實(shí)際上使用的是另一個(gè)更實(shí)用的四層模型,即 TCP/IP 網(wǎng)絡(luò)模型。 TCP/IP 模型,把網(wǎng)絡(luò)互聯(lián)的框架分為應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、網(wǎng)絡(luò)接口層等四層,其中,
?應(yīng)用層,負(fù)責(zé)向用戶(hù)提供一組應(yīng)用程序,比如 HTTP、FTP、DNS 等。
?傳輸層,負(fù)責(zé)端到端的通信,比如 TCP、UDP 等。
?網(wǎng)絡(luò)層,負(fù)責(zé)網(wǎng)絡(luò)包的封裝、尋址和路由,比如 IP、ICMP 等。
?網(wǎng)絡(luò)接口層,負(fù)責(zé)網(wǎng)絡(luò)包在物理網(wǎng)絡(luò)中的傳輸,比如 MAC 尋址、錯(cuò)誤偵測(cè)以及通過(guò)網(wǎng)卡傳輸網(wǎng)絡(luò)幀等。
TCP/IP 與 OSI 模型的關(guān)系如下圖:
雖說(shuō) Linux 實(shí)際按照 TCP/IP 模型,實(shí)現(xiàn)了網(wǎng)絡(luò)協(xié)議棧,但在平時(shí)的學(xué)習(xí)交流中,我們習(xí)慣上還是用 OSI 七層模型來(lái)描述。 比如,說(shuō)到七層和四層負(fù)載均衡,對(duì)應(yīng)的分別是 OSI 模型中的應(yīng)用層和傳輸層(而它們對(duì)應(yīng)到 TCP/IP 模型中,實(shí)際上是四層和三層)。
2 Linux網(wǎng)絡(luò)棧
有了 TCP/IP 模型后,在進(jìn)行網(wǎng)絡(luò)傳輸時(shí),數(shù)據(jù)包就會(huì)按照協(xié)議棧,對(duì)上一層發(fā)來(lái)的數(shù)據(jù)進(jìn)行逐層處理;然后封裝上該層的協(xié)議頭,再發(fā)送給下一層。 當(dāng)然,網(wǎng)絡(luò)包在每一層的處理邏輯,都取決于各層采用的網(wǎng)絡(luò)協(xié)議。比如在應(yīng)用層,一個(gè)提供 REST API 的應(yīng)用,可以使用 HTTP 協(xié)議,把它需要傳輸?shù)?JSON 數(shù)據(jù)封裝到 HTTP 協(xié)議中,然后向下傳遞給 TCP 層。 而封裝做的事情就很簡(jiǎn)單了,只是在原來(lái)的負(fù)載前后,增加固定格式的元數(shù)據(jù),原始的負(fù)載數(shù)據(jù)并不會(huì)被修改。 比如,以通過(guò) TCP 協(xié)議通信的網(wǎng)絡(luò)包為例,通過(guò)下面這張圖,我們可以看到,應(yīng)用程序數(shù)據(jù)在每個(gè)層的封裝格式。
其中:
?傳輸層在應(yīng)用程序數(shù)據(jù)前面增加了 TCP 頭;
?網(wǎng)絡(luò)層在 TCP 數(shù)據(jù)包前增加了 IP 頭;
?而網(wǎng)絡(luò)接口層,又在 IP 數(shù)據(jù)包前后分別增加了幀頭和幀尾。
這些新增的頭部和尾部,增加了網(wǎng)絡(luò)包的大小,但我們都知道,物理鏈路中并不能傳輸任意大小的數(shù)據(jù)包。 網(wǎng)絡(luò)接口配置的最大傳輸單元(MTU),就規(guī)定了最大的 IP 包大小。在我們最常用的以太網(wǎng)中,MTU 默認(rèn)值是 1500bytes(這也是 Linux 的默認(rèn)值)。 在Linux操作系統(tǒng)中執(zhí)行 ifconfig 可以查看到每個(gè)網(wǎng)卡的mtu值,有1450、1500等不同的值。
[root@dev ~]# ifconfig cni0: flags=4163一旦網(wǎng)絡(luò)包超過(guò) MTU 的大小,就會(huì)在網(wǎng)絡(luò)層分片,以保證分片后的 IP 包不大于 MTU 值。 顯然,MTU 越大,需要的分包也就越少,自然,網(wǎng)絡(luò)吞吐能力就越好。 理解了 TCP/IP 網(wǎng)絡(luò)模型和網(wǎng)絡(luò)包的封裝原理后,對(duì)Linux 內(nèi)核中的網(wǎng)絡(luò)棧,其實(shí)也類(lèi)似于 TCP/IP 的四層結(jié)構(gòu)。 如下圖所示,就是 Linux 通用 IP 網(wǎng)絡(luò)棧的示意圖:mtu 1450 inet 10.244.0.1 netmask 255.255.255.0 broadcast 10.244.0.255 inet6 fe80:53ff638b prefixlen 64 scopeid 0x20 ether 665363:8b txqueuelen 1000 (Ethernet) RX packets 124 bytes 12884 (12.5 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 122 bytes 29636 (28.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker0: flags=4099 mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02129e:91 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens33: flags=4163 mtu 1500 inet 192.168.2.129 netmask 255.255.255.0 broadcast 192.168.2.255 inet6 fe80:989b8e3b prefixlen 64 scopeid 0x20 ether 00295e:32 txqueuelen 1000 (Ethernet) RX packets 131 bytes 13435 (13.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 73 bytes 17977 (17.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
從上到下來(lái)看這個(gè)網(wǎng)絡(luò)棧,你可以發(fā)現(xiàn),
?最上層的應(yīng)用程序,需要通過(guò)系統(tǒng)調(diào)用,來(lái)跟套接字接口進(jìn)行交互;
?套接字的下面,就是我們前面提到的傳輸層、網(wǎng)絡(luò)層和網(wǎng)絡(luò)接口層;
?最底層,則是網(wǎng)卡驅(qū)動(dòng)程序以及物理網(wǎng)卡設(shè)備。
網(wǎng)卡是發(fā)送和接收網(wǎng)絡(luò)包的基本設(shè)備。 在系統(tǒng)啟動(dòng)過(guò)程中,網(wǎng)卡通過(guò)內(nèi)核中的網(wǎng)卡驅(qū)動(dòng)程序注冊(cè)到系統(tǒng)中。而在網(wǎng)絡(luò)收發(fā)過(guò)程中,內(nèi)核通過(guò)中斷跟網(wǎng)卡進(jìn)行交互。 網(wǎng)絡(luò)包的處理非常復(fù)雜,所以,網(wǎng)卡硬中斷只處理最核心的網(wǎng)卡數(shù)據(jù)讀取或發(fā)送,而協(xié)議棧中的大部分邏輯,都會(huì)放到軟中斷中處理。
3 Linux網(wǎng)絡(luò)包收發(fā)流程
了解了 Linux 網(wǎng)絡(luò)棧后,我們?cè)賮?lái)看看, Linux 到底是怎么收發(fā)網(wǎng)絡(luò)包的。 PS:以下內(nèi)容都以物理網(wǎng)卡為例。Linux 還支持眾多的虛擬網(wǎng)絡(luò)設(shè)備,而它們的網(wǎng)絡(luò)收發(fā)流程會(huì)有一些差別。
3.1 網(wǎng)絡(luò)包的接收流程
我們先來(lái)看網(wǎng)絡(luò)包的接收流程。
1. 當(dāng)一個(gè)網(wǎng)絡(luò)幀到達(dá)網(wǎng)卡后,網(wǎng)卡會(huì)通過(guò) DMA 方式,把這個(gè)網(wǎng)絡(luò)包放到收包隊(duì)列中;然后通過(guò)硬中斷,告訴中斷處理程序已經(jīng)收到了網(wǎng)絡(luò)包。
2. 接著,網(wǎng)卡中斷處理程序會(huì)為網(wǎng)絡(luò)幀分配內(nèi)核數(shù)據(jù)結(jié)構(gòu)(sk_buff),并將其拷貝到 sk_buff 緩沖區(qū)中;然后再通過(guò)軟中斷,通知內(nèi)核收到了新的網(wǎng)絡(luò)幀。
3. 接下來(lái),內(nèi)核協(xié)議棧從緩沖區(qū)中取出網(wǎng)絡(luò)幀,并通過(guò)網(wǎng)絡(luò)協(xié)議棧,從下到上逐層處理這個(gè)網(wǎng)絡(luò)幀。比如,
在鏈路層檢查報(bào)文的合法性,找出上層協(xié)議的類(lèi)型( IPv4 還是 IPv6),再去掉幀頭、幀尾,然后交給網(wǎng)絡(luò)層。
1. 網(wǎng)絡(luò)層取出 IP 頭,判斷網(wǎng)絡(luò)包下一步的走向,比如是交給上層處理還是轉(zhuǎn)發(fā)。當(dāng)網(wǎng)絡(luò)層確認(rèn)這個(gè)包是要發(fā)送到本機(jī)后,就會(huì)取出上層協(xié)議的類(lèi)型(TCP 還是 UDP),去掉 IP 頭,再交給傳輸層處理。
2. 傳輸層取出 TCP 頭或者 UDP 頭后,根據(jù) < 源 IP、源端口、目的 IP、目的端口 > 四元組作為標(biāo)識(shí),找出對(duì)應(yīng)的 Socket,并把數(shù)據(jù)拷貝到 Socket 的接收緩存中。
3. 最后,應(yīng)用程序就可以使用 Socket 接口,讀取到新接收到的數(shù)據(jù)了。
具體過(guò)程如下圖所示,這張圖的左半部分表示接收流程,而圖中的粉色箭頭則表示網(wǎng)絡(luò)包的處理路徑。
3.2 網(wǎng)絡(luò)包的發(fā)送流程
網(wǎng)絡(luò)包的發(fā)送流程就是上圖的右半部分,很容易發(fā)現(xiàn),網(wǎng)絡(luò)包的發(fā)送方向,正好跟接收方向相反。 首先,應(yīng)用程序調(diào)用 Socket API(比如 sendmsg)發(fā)送網(wǎng)絡(luò)包。 由于這是一個(gè)系統(tǒng)調(diào)用,所以會(huì)陷入到內(nèi)核態(tài)的套接字層中。套接字層會(huì)把數(shù)據(jù)包放到 Socket 發(fā)送緩沖區(qū)中。 接下來(lái),網(wǎng)絡(luò)協(xié)議棧從 Socket 發(fā)送緩沖區(qū)中,取出數(shù)據(jù)包;再按照 TCP/IP 棧,從上到下逐層處理。 比如,傳輸層和網(wǎng)絡(luò)層,分別為其增加 TCP 頭和 IP 頭,執(zhí)行路由查找確認(rèn)下一跳的 IP,并按照 MTU 大小進(jìn)行分片。 分片后的網(wǎng)絡(luò)包,再送到網(wǎng)絡(luò)接口層,進(jìn)行物理地址尋址,以找到下一跳的 MAC 地址。然后添加幀頭和幀尾,放到發(fā)包隊(duì)列中。這一切完成后,會(huì)有軟中斷通知驅(qū)動(dòng)程序:發(fā)包隊(duì)列中有新的網(wǎng)絡(luò)幀需要發(fā)送。 最后,驅(qū)動(dòng)程序通過(guò) DMA ,從發(fā)包隊(duì)列中讀出網(wǎng)絡(luò)幀,并通過(guò)物理網(wǎng)卡把它發(fā)送出去。 在不同的網(wǎng)絡(luò)協(xié)議處理下,給我們的網(wǎng)絡(luò)數(shù)據(jù)包加上了各種頭部,這保證了網(wǎng)絡(luò)數(shù)據(jù)在各層物理設(shè)備的流轉(zhuǎn)下可以正確抵達(dá)目的地。 收到處理后的網(wǎng)絡(luò)數(shù)據(jù)包后,接受端再通過(guò)網(wǎng)絡(luò)協(xié)議將頭部字段去除,得到原始的網(wǎng)絡(luò)數(shù)據(jù)。 下圖是客戶(hù)端與服務(wù)器之間用網(wǎng)絡(luò)協(xié)議連接通信的過(guò)程:
Linux 網(wǎng)絡(luò)根據(jù) TCP/IP 模型,構(gòu)建其網(wǎng)絡(luò)協(xié)議棧。TCP/IP 模型由應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、網(wǎng)絡(luò)接口層等四層組成,這也是 Linux 網(wǎng)絡(luò)棧最核心的構(gòu)成部分。 應(yīng)用程序通過(guò)套接字接口發(fā)送數(shù)據(jù)包時(shí),先要在網(wǎng)絡(luò)協(xié)議棧中從上到下逐層處理,然后才最終送到網(wǎng)卡發(fā)送出去;而接收數(shù)據(jù)包時(shí),也要先經(jīng)過(guò)網(wǎng)絡(luò)棧從下到上的逐層處理,最后送到應(yīng)用程序。 了解 Linux 網(wǎng)絡(luò)的基本原理和收發(fā)流程后,你肯定迫不及待想知道,如何去觀(guān)察網(wǎng)絡(luò)的性能情況。具體而言,哪些指標(biāo)可以用來(lái)衡量 Linux 的網(wǎng)絡(luò)性能呢?
4 常用網(wǎng)絡(luò)相關(guān)命令
分析網(wǎng)絡(luò)問(wèn)題的第一步,通常是查看網(wǎng)絡(luò)接口的配置和狀態(tài)。你可以使用 ifconfig 或者 ip 命令,來(lái)查看網(wǎng)絡(luò)的配置。
ifconfig 和 ip 分別屬于軟件包 net-tools 和 iproute2,iproute2 是 net-tools 的下一代,通常情況下它們會(huì)在發(fā)行版中默認(rèn)安裝。
以網(wǎng)絡(luò)接口 ens33 為例,可以運(yùn)行下面的兩個(gè)命令,查看它的配置和狀態(tài):
[root@dev ~]# ifconfig ens33 ens33: flags=4163可以看到,ifconfig 和 ip 命令輸出的指標(biāo)基本相同,只是顯示格式略微不同。比如,它們都包括了網(wǎng)絡(luò)接口的狀態(tài)標(biāo)志、MTU 大小、IP、子網(wǎng)、MAC 地址以及網(wǎng)絡(luò)包收發(fā)的統(tǒng)計(jì)信息。 有幾個(gè)字段可以重點(diǎn)關(guān)注下: 第一,網(wǎng)絡(luò)接口的狀態(tài)標(biāo)志。ifconfig 輸出中的 RUNNING ,或 ip 輸出中的 LOWER_UP ,都表示物理網(wǎng)絡(luò)是連通的,即網(wǎng)卡已經(jīng)連接到了交換機(jī)或者路由器中。如果你看不到它們,通常表示網(wǎng)線(xiàn)被拔掉了。 第二,MTU 的大小。MTU 默認(rèn)大小是 1500,根據(jù)網(wǎng)絡(luò)架構(gòu)的不同(比如是否使用了 VXLAN 等疊加網(wǎng)絡(luò)),你可能需要調(diào)大或者調(diào)小 MTU 的數(shù)值。 第三,網(wǎng)絡(luò)接口的 IP 地址、子網(wǎng)以及 MAC 地址。這些都是保障網(wǎng)絡(luò)功能正常工作所必需的,你需要確保配置正確。 第四,網(wǎng)絡(luò)收發(fā)的字節(jié)數(shù)、包數(shù)、錯(cuò)誤數(shù)以及丟包情況,特別是 TX ( Transmit發(fā)送 )和 RX(Receive接收 ) 部分的 errors、dropped、overruns、carrier 以及 collisions 等指標(biāo)不為 0 時(shí),通常表示出現(xiàn)了網(wǎng)絡(luò)問(wèn)題。其中:mtu 1500 inet 192.168.2.129 netmask 255.255.255.0 broadcast 192.168.2.255 inet6 fe80:989b8e3b prefixlen 64 scopeid 0x20 ether 00295e:32 txqueuelen 1000 (Ethernet) RX packets 249 bytes 22199 (21.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 106 bytes 22636 (22.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@dev ~]# [root@dev ~]# ip -s addr show ens33 2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00295e:32 brd ffffff:ff inet 192.168.2.129/24 brd 192.168.2.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80:989b8e3b/64 scope link noprefixroute valid_lft forever preferred_lft forever RX: bytes packets errors dropped overrun mcast 24877 279 0 0 0 0 TX: bytes packets errors dropped carrier collsns 24616 123 0 0 0 0
? errors 表示發(fā)生錯(cuò)誤的數(shù)據(jù)包數(shù),比如校驗(yàn)錯(cuò)誤、幀同步錯(cuò)誤等;
? dropped 表示丟棄的數(shù)據(jù)包數(shù),即數(shù)據(jù)包已經(jīng)收到了 Ring Buffer,但因?yàn)閮?nèi)存不足等原因丟包;
? overruns 表示超限數(shù)據(jù)包數(shù),即網(wǎng)絡(luò) I/O 速度過(guò)快,導(dǎo)致 Ring Buffer 中的數(shù)據(jù)包來(lái)不及處理(隊(duì)列滿(mǎn))而導(dǎo)致的丟包;
? carrier 表示發(fā)生 carrirer 錯(cuò)誤的數(shù)據(jù)包數(shù),比如雙工模式不匹配、物理電纜出現(xiàn)問(wèn)題等;
? collisions 表示碰撞數(shù)據(jù)包數(shù)。
4.1 套接字信息
套接字接口在網(wǎng)絡(luò)程序功能中是內(nèi)核與應(yīng)用層之間的接口。TCP/IP 協(xié)議棧的所有數(shù)據(jù)和控制功能都來(lái)自于套接字接口,與 OSI 網(wǎng)絡(luò)分層模型相比,TCP/IP 協(xié)議棧本身在傳輸層以上就不包含任何其他協(xié)議。
在 Linux 操作系統(tǒng)中,替代傳輸層以上協(xié)議實(shí)體的標(biāo)準(zhǔn)接口,稱(chēng)為套接字,它負(fù)責(zé)實(shí)現(xiàn)傳輸層以上所有的功能,可以說(shuō)套接字是 TCP/IP 協(xié)議棧對(duì)外的窗口。
ifconfig 和 ip 只顯示了網(wǎng)絡(luò)接口收發(fā)數(shù)據(jù)包的統(tǒng)計(jì)信息,但在實(shí)際的性能問(wèn)題中,網(wǎng)絡(luò)協(xié)議棧中的統(tǒng)計(jì)信息,我們也必須關(guān)注,可以用 netstat 或者 ss ,來(lái)查看套接字、網(wǎng)絡(luò)棧、網(wǎng)絡(luò)接口以及路由表的信息。 我個(gè)人更推薦,使用 ss 來(lái)查詢(xún)網(wǎng)絡(luò)的連接信息,因?yàn)樗?netstat 提供了更好的性能(速度更快)。 比如,你可以執(zhí)行下面的命令,查詢(xún)套接字信息:
# head -n 4 表示只顯示前面4行 # -l 表示只顯示監(jiān)聽(tīng)套接字 # -n 表示顯示數(shù)字地址和端口(而不是名字) # -p 表示顯示進(jìn)程信息 [root@dev ~]# netstat -nlp | head -n 4 Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 952/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 11/master # -l 表示只顯示監(jiān)聽(tīng)套接字 # -t 表示只顯示 TCP 套接字 # -n 表示顯示數(shù)字地址和端口(而不是名字) # -p 表示顯示進(jìn)程信息 $ ss -ltnp | head -n 4
netstat 和 ss 的輸出也是類(lèi)似的,都展示了套接字的狀態(tài)、接收隊(duì)列、發(fā)送隊(duì)列、本地地址、遠(yuǎn)端地址、進(jìn)程 PID 和進(jìn)程名稱(chēng)等。 其中,接收隊(duì)列(Recv-Q)和發(fā)送隊(duì)列(Send-Q)需要你特別關(guān)注,它們通常應(yīng)該是 0。 當(dāng)你發(fā)現(xiàn)它們不是 0 時(shí),說(shuō)明有網(wǎng)絡(luò)包的堆積發(fā)生。當(dāng)然還要注意,在不同套接字狀態(tài)下,它們的含義不同。 當(dāng)套接字處于連接狀態(tài)(Established)時(shí),
? Recv-Q 表示套接字緩沖還沒(méi)有被應(yīng)用程序取走的字節(jié)數(shù)(即接收隊(duì)列長(zhǎng)度)。
? Send-Q 表示還沒(méi)有被遠(yuǎn)端主機(jī)確認(rèn)的字節(jié)數(shù)(即發(fā)送隊(duì)列長(zhǎng)度)。
當(dāng)套接字處于監(jiān)聽(tīng)狀態(tài)(Listening)時(shí),
? Recv-Q 表示全連接隊(duì)列的長(zhǎng)度。
? Send-Q 表示全連接隊(duì)列的最大長(zhǎng)度。
所謂全連接,是指服務(wù)器收到了客戶(hù)端的 ACK,完成了 TCP 三次握手,然后就會(huì)把這個(gè)連接挪到全連接隊(duì)列中。 這些全連接中的套接字,還需要被 accept() 系統(tǒng)調(diào)用取走,服務(wù)器才可以開(kāi)始真正處理客戶(hù)端的請(qǐng)求。 與全連接隊(duì)列相對(duì)應(yīng)的,還有一個(gè)半連接隊(duì)列。所謂半連接是指還沒(méi)有完成 TCP 三次握手的連接,連接只進(jìn)行了一半。 服務(wù)器收到了客戶(hù)端的 SYN 包后,就會(huì)把這個(gè)連接放到半連接隊(duì)列中,然后再向客戶(hù)端發(fā)送 SYN+ACK 包。
4.2 連接統(tǒng)計(jì)信息
類(lèi)似的,使用 netstat 或 ss ,也可以查看協(xié)議棧的信息:
[root@dev ~]# netstat -s ... Tcp: 1898 active connections openings 1502 passive connection openings 24 failed connection attempts 1304 connection resets received 178 connections established 133459 segments received 133428 segments send out 22 segments retransmited 0 bad segments received. 1400 resets sent ... [root@dev ~]# ss -s Total: 1700 (kernel 2499) TCP: 340 (estab 178, closed 144, orphaned 0, synrecv 0, timewait 134/0), ports 0 Transport Total IP IPv6 * 2499 - - RAW 1 0 1 UDP 5 3 2 TCP 196 179 17 INET 202 182 20 FRAG 0 0 0這些協(xié)議棧的統(tǒng)計(jì)信息都很直觀(guān)。 ss 只顯示已經(jīng)連接、關(guān)閉、孤兒套接字等簡(jiǎn)要統(tǒng)計(jì),而 netstat 則提供的是更詳細(xì)的網(wǎng)絡(luò)協(xié)議棧信息,展示了 TCP 協(xié)議的主動(dòng)連接、被動(dòng)連接、失敗重試、發(fā)送和接收的分段數(shù)量等各種信息。
4.3 連通性和延時(shí)
通常使用 ping ,來(lái)測(cè)試遠(yuǎn)程主機(jī)的連通性和延時(shí),而ping基于 ICMP 協(xié)議。 比如,執(zhí)行下面的命令,你就可以測(cè)試本機(jī)到 192.168.2.129 這個(gè) IP 地址的連通性和延時(shí):
[root@dev ~]# ping -c3 192.168.2.129 PING 192.168.2.129 (192.168.2.129) 56(84) bytes of data. 64 bytes from 192.168.2.129: icmp_seq=1 ttl=64 time=0.026 ms 64 bytes from 192.168.2.129: icmp_seq=2 ttl=64 time=0.016 ms 64 bytes from 192.168.2.129: icmp_seq=3 ttl=64 time=0.015 ms --- 192.168.2.129 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1998ms rtt min/avg/max/mdev = 0.015/0.019/0.026/0.005 msping 的輸出,可以分為兩部分。
1. 第一部分,是每個(gè) ICMP 請(qǐng)求的信息,包括 ICMP 序列號(hào)(icmp_seq)、TTL(生存時(shí)間,或者跳數(shù))以及往返延時(shí)。
2. 第二部分,則是三次 ICMP 請(qǐng)求的匯總。
比如上面的示例顯示,發(fā)送了 3 個(gè)網(wǎng)絡(luò)包,并且接收到 3 個(gè)響應(yīng),沒(méi)有丟包發(fā)生,這說(shuō)明測(cè)試主機(jī)到 192.168.2.129是連通的;平均往返延時(shí)(RTT)是 0.026 ms,也就是從發(fā)送 ICMP 開(kāi)始,到接收到主機(jī)回復(fù)的確認(rèn),總共經(jīng)歷的時(shí)間。
-
Linux
+關(guān)注
關(guān)注
87文章
11292瀏覽量
209322 -
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7488瀏覽量
87848 -
路由器
+關(guān)注
關(guān)注
22文章
3728瀏覽量
113700 -
網(wǎng)絡(luò)模型
+關(guān)注
關(guān)注
0文章
44瀏覽量
8425
原文標(biāo)題:深入介紹Linux網(wǎng)絡(luò)知識(shí)
文章出處:【微信號(hào):c-stm32,微信公眾號(hào):STM32嵌入式開(kāi)發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論