Linux服務器網卡深度解析:從ifconfig輸出到生產環境性能調優實戰
- Linux服務器網卡深度解析:從ifconfig輸出到生產環境性能調優實戰
- 一、背景
- 二、生產環境的服務器部署情況
- 三、拆解一個真實的 ifconfig 輸出
- 1、先看 MAC 地址
- 2、再看設備的 interrupt 和 memory
- 3、了解Linux網卡的命名規則
- 四、流量流向的情況
- 五、虛擬機 ifconfig 的情況
- 六、總結
Linux服務器網卡深度解析:從ifconfig輸出到生產環境性能調優實戰
一、背景
2025年4月9號,客戶對我們生產環境的接口進行了15000TPS的壓力測試,客戶在微信群里反饋,只能壓測到9000左右,速度上不去了。
看到這個消息之后,我有兩個反應:
1、情緒方面,講真我是有點生氣的,想罵人,但還忍住了。
客戶在我們不知情的情況下,對生產環境的接口做壓力測試,TPS這么高,容易把帶寬打滿,會影響到其他客戶;我能理解客戶為什么不提前告知,大概率就是想出其不意,防止我們事先做準備,但這做法確實比較負面和負能量;要么就是我自己想多了,對方的技術人員沒有意識到這種問題會產生什么影響。
2、要趕緊查看一下,帶寬是否被打滿,是不是影響其他客戶。
由此涉及到了本次想分享的主題,作為一個 Linux 后端開發,我也經常使用 ifconfig 命令查看一些信息,但從來沒有深究過,今天是想總結一下了。
這么多年的開發經驗,進過運營商機房、見過機房里面的機架、服務器。大學期間,組裝過臺式機(算是見過網卡),安裝過操作系統(要安裝網卡驅動的),也就僅限于此。
所以今天,我想分享一下如何根據 ifconfig 命令理解網卡信息和網卡流量。
二、生產環境的服務器部署情況
客戶的流量,經過公網到達我們北京機房,首先是經過防火墻設備、然后到達nginx服務器(10.90.36.248),經過nginx的轉發最后到達后端業務程序(10.90.36.117、10.90.36.118)。
這期間,流量還會經過路由器和交換機,我還不太清晰,但不影響理解,也就不列出來了。
1、10.90.36.248 服務器是一臺物理機,安裝了 nginx,用作負載均衡;
2、10.90.36.117、10.90.36.118 服務器是一臺虛擬機,部署業務程序,用作后端服務;
三、拆解一個真實的 ifconfig 輸出
下面這段 來自于 10.90.36.248 nginx 服務器的 ifconfig 命令的輸出。
可以看到好幾個網卡信息,比如:bond1、bond1:1、enp8s0f0、enp8s0f1、enp8s0f2、enp8s0f3、ens2f0、ens2f1、lo,該如何拆解呢?
憑直覺,我們可以給這些網卡進行分類:
1、bond1、bond1:1
2、enp8s0f0、enp8s0f1、enp8s0f2、enp8s0f3
3、ens2f0、ens2f1、
4、lo
大家應該能猜到,這其中有真實的物理網卡、也有虛擬出來的虛擬網卡(或者叫邏輯網卡)。
那怎么區分哪些是物理網卡,哪些是虛擬網卡?
[app@phy01 ~]$ ifconfig
bond1: flags=5187<UP,BROADCAST,RUNNING,MASTER,MULTICAST> mtu 1500inet 10.90.36.248 netmask 255.255.255.0 broadcast 10.90.36.255inet6 fe80::327b:acff:fe77:37d8 prefixlen 64 scopeid 0x20<link>ether 20:6b:ac:67:32:d9 txqueuelen 1000 (Ethernet)RX packets 1391424129086 bytes 401438743483080 (365.1 TiB)RX errors 124693 dropped 17 overruns 124633 frame 60TX packets 1262250505591 bytes 198488434823174 (180.5 TiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0bond1:1: flags=5187<UP,BROADCAST,RUNNING,MASTER,MULTICAST> mtu 1500inet 10.90.36.238 netmask 255.255.255.255 broadcast 0.0.0.0ether 20:6b:ac:67:32:d9 txqueuelen 1000 (Ethernet)enp8s0f0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500ether 77:ee:cb:75:22:21 txqueuelen 1000 (Ethernet)RX packets 13422608 bytes 1789398012 (1.6 GiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0device memory 0xc7360000-c737ffffenp8s0f1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500ether 77:ee:cb:75:22:22 txqueuelen 1000 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0device memory 0xc7340000-c735ffffenp8s0f2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500ether 77:ee:cb:75:22:23 txqueuelen 1000 (Ethernet)RX packets 27993427 bytes 10295585352 (9.5 GiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0device memory 0xc7320000-c733ffffenp8s0f3: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500ether 77:ee:cb:75:22:24 txqueuelen 1000 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0device memory 0xc7300000-c731ffffens2f0: flags=6211<UP,BROADCAST,RUNNING,SLAVE,MULTICAST> mtu 1500ether 20:6b:ac:67:32:d9 txqueuelen 1000 (Ethernet)RX packets 1391340237564 bytes 401431888921467 (365.1 TiB)RX errors 124693 dropped 8 overruns 124633 frame 60TX packets 1262250505591 bytes 198488434823174 (180.5 TiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0device interrupt 80 memory 0x23fff000000-23fff7fffffens2f1: flags=6211<UP,BROADCAST,RUNNING,SLAVE,MULTICAST> mtu 1500ether 20:6b:ac:67:32:d9 txqueuelen 1000 (Ethernet)RX packets 83891522 bytes 6854561613 (6.3 GiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0device interrupt 100 memory 0x23ffe000000-23ffe7ffffflo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 1 (Local Loopback)RX packets 825841 bytes 110153455 (105.0 MiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 825841 bytes 110153455 (105.0 MiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[app@phy01 ~]$
1、先看 MAC 地址
我們知道 MAC 地址是用來唯一標識一個設備的,所以,我們可以通過 MAC 地址來區分物理網卡和虛擬網卡。
在 ifconfig 命令的輸出中,ether 指的就是 MAC 地址。
你會發現,bond1、bond1:1、ens2f0、ens2f1 的MAC 地址都是 20:6b:ac:67:32:d9,
那這些都是同一個物理網卡嗎?
而 enp8s0f0、enp8s0f1、enp8s0f2、enp8s0f3 的 MAC 地址也有規律,分別是:
77:ee:cb:75:22:21
77:ee:cb:75:22:22
77:ee:cb:75:22:23
77:ee:cb:75:22:24
那這些是不同同的物理網卡嗎?
2、再看設備的 interrupt 和 memory
device interrupt 是設備的中斷號,而 device memory 是設備的內存地址。
這兩個屬性,是操作系統分配給硬件的資源,可以用來作為是不是物理網卡的直接證據。
雖然 bond1、bond1:1、ens2f0、ens2f1 的MAC 地址都是 20:6b:ac:67:32:d9,但
ens2f0 的 interrupt 是 80,memory 是 0x23fff000000-23fff7fffff
ens2f1 的 interrupt 是 100,memory 是 0x23ffe000000-23ffe7fffff
而 bond1、bond1:1 是沒有interrupt 和 memory 的。
通過這些信息,我們可以知道,
bond1 是一個綁定主接口(有 MASTER 標志),聚合了 ens2f0 和 ens2f1 (有 SLAVE 標志 并且 他們有相同 MAC 地址),
bond1還具有兩個 IP 地址,主地址 10.90.36.248 和 別名地址 10.90.36.238(bond1:1 是 bond1 的別名接口)。
所以可以得知, ens2f0 和 ens2f1 大概率是:一個獨立的含有2個端口的真實物理網卡。
而 bond1 是基于 ens2f0 和 ens2f1 的虛擬網卡。
bond1:1 又是基于 bond1 的別名。
對 enp8s0f0、enp8s0f1、enp8s0f2、enp8s0f3 的理解就比較簡單了,他們都有不同的 MAC地址,也有不同的device memory,
所以大概率是:一個獨立的含有4個端口的真實物理網卡。
3、了解Linux網卡的命名規則
從上面的ifconfig輸出中,我們看到了各種各樣的網卡名稱,如ens2f0、enp8s0f0等。這些名稱并非隨意取的,而是遵循了Linux網卡的命名規則,也稱為"可預測網絡接口名稱"(Predictable Network Interface Names)。
在傳統的Linux系統中,網卡命名通常是eth0、eth1這樣的格式。但這種命名方式存在一個問題:當系統重啟或硬件變更時,網卡的順序可能會改變,導致eth0變成eth1,反之亦然。為了解決這個問題,現代Linux系統采用了更可預測的命名方案:
-
ens2f0的命名解析:
- en: 表示Ethernet,即以太網設備
- s2: 表示插槽(slot)2
- f0: 表示該插槽上的第一個端口(function 0)
-
enp8s0f0的命名解析:
- en: 表示Ethernet
- p8: 表示PCI總線號8
- s0: 表示該總線上的插槽0
- f0: 表示該插槽上的第一個端口
-
bond1:
- 這是一個虛擬接口,通過將多個物理接口綁定在一起組成的
- 數字1表示這是系統中的第二個bond接口(從0開始計數)
-
lo:
- 代表loopback,即回環接口
- 用于本機通信,IP地址為127.0.0.1
了解這些命名規則有助于我們僅通過網卡名稱就能識別出網卡在系統中的物理位置,以及它們的類型和功能。
四、流量流向的情況
我們繼續看生產環境,流量是如何流向的情況。
bond1入站、ens2f0入站,都是 101.16Mb/s
bond1出站、ens2f0出站,都是 108.14Mb/s
在綁定模式中,流量默認只通過一個從屬接口(ens2f0)接收,另一接口(ens2f1)處于備用狀態,因此 ens2f0 的入站流量與 bond1 完全一致。
至于入站流量與出站流量不一致,是因為nginx服務器會添加一些HTTP請求頭導致的差異。
五、虛擬機 ifconfig 的情況
在我們的生產環境中,還有很多的虛擬機,它們的 ifconfig 更簡單,再來看一個虛擬機下的 ifconfig 的輸出。
[root@kundebug ~]$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.18.249.178 netmask 255.255.240.0 broadcast 172.18.255.255inet6 fe80::216:3eff:fe08:efe8 prefixlen 64 scopeid 0x20<link>ether 00:16:3e:08:ef:e8 txqueuelen 1000 (Ethernet)RX packets 6651745 bytes 2931130548 (2.7 GiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 5152881 bytes 3191851949 (2.9 GiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 1000 (Local Loopback)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[root@kundebug ~]$
在這臺虛擬機的 ifconfig 輸出中,看不到 device interrupt 和 device memory 信息。
而根據 MAC 地址 00:16:3e:08:ef:e8 的前3個字節 00:16:3e ,我們可以在IEEE官網上查到這個 MAC 地址的廠商信息,如下:
前3字節 00:16:3e 屬于 Xensource(常見于虛擬化環境,如 Xen/KVM)。
所有合法的 MAC 地址都可以通過 IEEE 官網查詢到它的廠商信息,每個 MAC 地址為全球唯一。
當然如果你用本文前面 ifconfig 輸出的信息中的 MAC 來查詢,是查不到的,因為已經被我修改過了,哈哈哈哈。
當然這個很好驗證了,我找了我們測試環境的一臺物理機,查到的廠商是華為的,這沒有問題。
六、總結
通過本文的分析,我們可以得出以下幾點關于Linux服務器網卡信息的理解要點:
-
物理網卡與虛擬網卡的區分:
- 物理網卡通常具有唯一的MAC地址,且會分配有device interrupt和device memory
- 虛擬網卡(如bond接口)通常沒有device interrupt和memory信息
- 虛擬機中的網卡(如eth0)雖然有MAC地址,但其MAC地址前綴通常表明其為虛擬化廠商分配
-
網卡命名規則:
- ens2f0這類命名通常表示物理網卡接口,其中數字標識不同的插槽和端口
- bond接口是將多個物理網卡綁定為一個邏輯接口,提高吞吐量和冗余性
- 像bond1:1這樣的別名接口允許在同一物理接口上配置多個IP地址
-
流量分析:
- 通過RX/TX packets和bytes可以監控網絡流量
- 在bond模式下,流量可能只通過一個活躍的從屬接口傳輸,其他接口處于備用狀態
- 關注errors、dropped、overruns等計數器可以幫助發現潛在的網絡問題
-
實際應用價值:
- 了解網卡信息有助于定位網絡瓶頸,如本文開頭提到的客戶壓測場景
- 對于后端開發人員,這些知識在性能優化和問題排查時非常寶貴
- 在高流量環境下,了解網卡配置可以幫助判斷是否需要硬件升級或配置調整
-
MAC地址識別:
- MAC地址的前3個字節(OUI)可以標識廠商
- 通過IEEE官網可以查詢MAC地址的廠商信息
- 這有助于判斷網卡的來源和類型(物理/虛擬)
作為Linux后端開發人員,掌握這些網絡基礎知識不僅有助于日常運維和問題排查,也能在系統設計和性能優化時做出更明智的決策。在高并發、高流量的生產環境中,這些知識尤為重要,可以幫助我們快速定位問題根源,提供更可靠的服務。