怎樣自建網(wǎng)站網(wǎng)頁優(yōu)化建議
寫在前面
- 考試整理相關(guān)筆記
- 分享一些 Linux 中網(wǎng)絡(luò)內(nèi)核參數(shù)調(diào)優(yōu)的筆記
- 理解不足小伙伴幫忙指正
對每個(gè)人而言,真正的職責(zé)只有一個(gè):找到自我。然后在心中堅(jiān)守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是對大眾理想的懦弱回歸,是隨波逐流,是對內(nèi)心的恐懼 ——赫爾曼·黑塞《德米安》
網(wǎng)絡(luò)優(yōu)化
Linux 網(wǎng)絡(luò)優(yōu)化是一個(gè)很大的概念,這里講的優(yōu)化主要是 傳輸層
和網(wǎng)絡(luò)層
的優(yōu)化.
Linux
和其他主流操作系統(tǒng)中的網(wǎng)絡(luò)流量
被抽象(協(xié)議分層與OSI參考模型)為一系列的硬件和軟件層次
。在每個(gè)分層上,發(fā)送端添加首部包裝信息,經(jīng)過路由器,接受端分離首部恢復(fù)數(shù)據(jù)。當(dāng)然路由器的傳遞也涉及網(wǎng)絡(luò)層和鏈路層的首部分離和添加.
簡單回顧:
分層 | 描述 |
---|---|
應(yīng)用層 | 應(yīng)用層涉及協(xié)議比較多TELNET,SSH,HTTP,SMTP,POP,SSL/TLS,FTP,MIME,HTML,SNMP,MIB…… ,主要負(fù)責(zé)聲明目標(biāo)地址(請求頭)以及寫入內(nèi)容(請求報(bào)文) |
表示層 | 表示層負(fù)責(zé)將機(jī)器特定的數(shù)據(jù)格式轉(zhuǎn)化為網(wǎng)絡(luò)標(biāo)準(zhǔn)的傳輸格式發(fā)送出去 |
會(huì)話層 | 會(huì)話層決定采用那種連接方式?同時(shí)標(biāo)記數(shù)據(jù)包的發(fā)送順序 |
傳輸層 | 傳輸層即進(jìn)行建立連接或者斷開連接,在兩個(gè)主機(jī)之間創(chuàng)建邏輯上的通信連接,確保數(shù)據(jù)是否到達(dá),沒到達(dá)重發(fā),保證數(shù)據(jù)的可靠性,涉及到的協(xié)議包括 TCP,UDP,DCDC |
網(wǎng)絡(luò)層 | 網(wǎng)絡(luò)層將數(shù)據(jù)從發(fā)送端主機(jī)發(fā)送到接收端主機(jī)。涉及到的協(xié)議包括ARP,IPv4,IPv6,ICMP(ping),IPsec 等 |
鏈路層 | 包括以太網(wǎng),無線LAN,PPP ,數(shù)據(jù)鏈路層負(fù)責(zé)實(shí)現(xiàn)每一個(gè)區(qū)間內(nèi)的通信。通信實(shí)際上是通過物理的傳輸介質(zhì)實(shí)現(xiàn)的,數(shù)據(jù)鏈路層在傳輸介質(zhì)互連的設(shè)備進(jìn)行數(shù)據(jù)處理。 |
物理層 | 硬件層,物理層將數(shù)據(jù)的01轉(zhuǎn)換為電壓和脈沖光 傳輸給物理的傳輸介質(zhì),相互直連的設(shè)備 通過MAC(Media Access Control,介質(zhì)訪問控制) 實(shí)現(xiàn)傳輸。物理層將MAC地址信息的首部附加到從網(wǎng)絡(luò)層轉(zhuǎn)發(fā)過來的數(shù)據(jù)上,將其發(fā)送到網(wǎng)絡(luò) 。 |
數(shù)據(jù)的流向整體是一個(gè)出棧入棧的過程,用應(yīng)用層開始,包裝數(shù)據(jù),化整為零,分段傳輸,然后到物理層為信號傳輸,這是進(jìn)棧,到達(dá)目標(biāo)IP,在通過碎片緩存區(qū)
化零為整,出棧到達(dá)應(yīng)用層。
傳輸層和網(wǎng)絡(luò)層的數(shù)據(jù)流轉(zhuǎn)
數(shù)據(jù)傳輸(出站) :
首先,應(yīng)用程序通過操作系統(tǒng)提供網(wǎng)絡(luò)套接字API(編程接口)
將數(shù)據(jù)寫入到socket
文件描述符, 即數(shù)據(jù)被寫入到 socket
文件,然后放到傳輸緩存
中,常見的協(xié)議包括TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報(bào)協(xié)議)。
這是時(shí)候操作系統(tǒng)內(nèi)核
從傳輸緩存
中提取數(shù)據(jù)
,根據(jù)網(wǎng)絡(luò)協(xié)議規(guī)范(TCP/UDP) 封裝數(shù)據(jù)到一個(gè)PDU(協(xié)議數(shù)據(jù)單元,TCP段/UDP數(shù)據(jù)報(bào))
,網(wǎng)絡(luò)層會(huì)添加 IP 頭部,形成 IP 數(shù)據(jù)報(bào)
。
將包含 PDU數(shù)據(jù)單元
的 IP 數(shù)據(jù)報(bào)
放到 設(shè)備傳輸隊(duì)列
,等待發(fā)送,網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序
定期檢查傳輸隊(duì)列
,獲取待發(fā)送的PDU
。驅(qū)動(dòng)程序?qū)?code>PDU數(shù)據(jù)從內(nèi)核空間
拷貝到網(wǎng)卡設(shè)備(NIC)
的內(nèi)存緩沖區(qū)
一旦PDU
被拷貝到網(wǎng)卡設(shè)備的內(nèi)存緩沖區(qū)
,網(wǎng)卡設(shè)備開始發(fā)送數(shù)據(jù)。數(shù)據(jù)發(fā)送過程可能涉及物理層操作,例如將數(shù)據(jù)轉(zhuǎn)換為電信號并發(fā)送到物理介質(zhì)(例如以太網(wǎng))。在數(shù)據(jù)傳輸過程中,網(wǎng)卡設(shè)備可能會(huì)引發(fā)中斷,通知操作系統(tǒng)數(shù)據(jù)傳輸已完成或需要進(jìn)一步處理。
這里要經(jīng)過 路由尋址,地址轉(zhuǎn)發(fā)
,到達(dá)目標(biāo)IP主機(jī),到達(dá)目標(biāo) IP 之后,會(huì)有個(gè)入棧操作
接受數(shù)據(jù)(入站) :
當(dāng)數(shù)據(jù)幀
到達(dá)網(wǎng)卡時(shí),網(wǎng)卡
會(huì)使用 DMA緩存區(qū)
將數(shù)據(jù)幀復(fù)制到接收緩沖區(qū)
。接收緩沖區(qū)
是在操作系統(tǒng)內(nèi)核中為接收數(shù)據(jù)包而分配的一塊內(nèi)存區(qū)域,一旦數(shù)據(jù)幀被復(fù)制到接收緩沖區(qū)
,網(wǎng)卡會(huì)向主機(jī)發(fā)起硬中斷
信號,通知操作系統(tǒng)有新的數(shù)據(jù)包
到達(dá)。
操作系統(tǒng)內(nèi)核
接收到硬中斷
信號后,會(huì)中斷當(dāng)前執(zhí)行的任務(wù),并進(jìn)入硬中斷
處理程序,在硬中斷處理程序中,操作系統(tǒng)內(nèi)核
會(huì)調(diào)度軟中斷
(軟中斷是一種延遲處理機(jī)制,它允許將數(shù)據(jù)包的處理推遲到適當(dāng)?shù)臅r(shí)機(jī),以提高系統(tǒng)性能)來處理接收到的數(shù)據(jù)包。。
軟中斷
處理程序會(huì)從接收緩沖區(qū)
中讀取數(shù)據(jù)包
,并進(jìn)行必要的處理。這包括解析數(shù)據(jù)包的各個(gè)層級協(xié)議頭部(例如以太網(wǎng)頭部
、IP頭部
等),將數(shù)據(jù)包移交給IP層
進(jìn)行進(jìn)一步的處理。
如果數(shù)據(jù)包大于 MTU(最大傳輸單元)
,需要分段傳輸,這里需要利用 碎片緩沖區(qū)
重新組裝為原始數(shù)據(jù)報(bào)
內(nèi)核封裝數(shù)據(jù)到協(xié)議數(shù)據(jù)單元(PDU)
,對等分層間傳輸數(shù)據(jù)的單位,物理層
的 PDU 是位(bit)
,數(shù)據(jù)鏈路層
的 PDU 是數(shù)據(jù)幀(frame)
,網(wǎng)絡(luò)層
的 PDU 是包(packet)
,更高層的 PDU 是數(shù)據(jù)報(bào)文(message)
. 一個(gè) PDU 包括上層的數(shù)據(jù)
加本層的數(shù)據(jù)頭部信息
。
網(wǎng)絡(luò)內(nèi)核調(diào)優(yōu)
通過上面的簡單回顧,可以了解到 網(wǎng)絡(luò)緩存
包括內(nèi)核緩存
,每個(gè)socket緩存
,碎片緩沖區(qū)
以及網(wǎng)卡的DMA緩沖區(qū)
。
可以通過配置上面不同的緩存區(qū)的內(nèi)核參數(shù)達(dá)到調(diào)優(yōu)的目的,具體的調(diào)優(yōu)參數(shù)配置可以結(jié)合上面的圖
系統(tǒng)級內(nèi)核參數(shù)(對緩存的動(dòng)作)
net.ipv4.tcp_mem,net.ipv4.udp_mem(單位是
Page 內(nèi)存頁,4K)
分別代表了TCP和UDP的系統(tǒng)層面內(nèi)存限制的值
,即網(wǎng)絡(luò)連接的內(nèi)存分配,包括三列:min,pressure,max
, net.ipv4.tcp_mem
即我們常講的 TCP 接收窗口大小
min
: TCP/UDP 使用低于這個(gè)值時(shí),內(nèi)核不會(huì)釋放這些緩存。pressure
:當(dāng) TCP/UDP 緩存超過這個(gè)值時(shí),內(nèi)核開始釋放緩存,減少使用量,直到低于 min 值。max
:所有 TCP/UDP 的 sockets 可以使用的最大內(nèi)存緩存值。
注意
:net.ipv4.tcp_mem和net.ipv4.udp_mem
是 pages 為單位,不是字節(jié)為單位,可以使用 getconf PAGESIZE 查看 page 大小的值(一般是 4096 字節(jié)=4K)
查看內(nèi)存頁的大小
┌──[root@liruilongs.github.io]-[~]
└─$getconf PAGESIZE
4096
內(nèi)核參數(shù)位置:
┌──[root@liruilongs.github.io]-[~]
└─$cat /proc/sys/net/ipv4/tcp_mem
472977 630639 945954
┌──[root@liruilongs.github.io]-[~]
└─$cat /proc/sys/net/ipv4/udp_mem
945957 1261278 1891914
┌──[root@liruilongs.github.io]-[~]
└─$
對于這兩個(gè)參數(shù)的調(diào)優(yōu),在使用 sar
來查看鏈路級的網(wǎng)絡(luò)性能數(shù)據(jù)
比如 sar -n EDEV 1 1
,顯示每個(gè)設(shè)備的發(fā)送和接收錯(cuò)誤信息
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$sar -n EDEV 1 1
Linux 3.10.0-693.el7.x86_64 (vms81.liruilongs.github.io) 2022年05月14日 _x86_64_ (2 CPU)22時(shí)53分07秒 IFACE rxerr/s txerr/s coll/s rxdrop/s txdrop/s txcarr/s rxfram/s rxfifo/s txfifo/s
22時(shí)53分08秒 ens32 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22時(shí)53分08秒 cali86e7ca9e9c2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22時(shí)53分08秒 cali13a4549bf1e 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22時(shí)53分08秒 cali5a282a7bbb0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22時(shí)53分08秒 cali12cf25006b5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22時(shí)53分08秒 cali45e02b0b21e 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22時(shí)53分08秒 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22時(shí)53分08秒 calicb34164ec79 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22時(shí)53分08秒 tunl0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22時(shí)53分08秒 docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00平均時(shí)間: IFACE rxerr/s txerr/s coll/s rxdrop/s txdrop/s txcarr/s rxfram/s rxfifo/s txfifo/s
平均時(shí)間: ens32 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均時(shí)間: cali86e7ca9e9c2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均時(shí)間: cali13a4549bf1e 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均時(shí)間: cali5a282a7bbb0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均時(shí)間: cali12cf25006b5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均時(shí)間: cali45e02b0b21e 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均時(shí)間: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均時(shí)間: calicb34164ec79 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均時(shí)間: tunl0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均時(shí)間: docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$
列 | 說明 |
---|---|
rxerr/s | 接收錯(cuò)誤率 |
txerr/s | 發(fā)送錯(cuò)誤率 |
co11/s | 發(fā)送時(shí)的以太網(wǎng)沖突率 |
rxdrop/s | 由于Linux內(nèi)核緩沖區(qū)不足而導(dǎo)致的接收幀丟棄率 |
txdrop/s | 由于Linux內(nèi)核緩沖區(qū)不足而導(dǎo)致的發(fā)送幀丟棄率 |
txcarr/s | 由于載波錯(cuò)誤而導(dǎo)致的發(fā)送幀丟棄率 |
rxfram/s | 由于幀對齊錯(cuò)誤而導(dǎo)致的接收幀丟棄率 |
rxfifo/s | 由于FIFO錯(cuò)誤而導(dǎo)致的接收幀丟棄率 |
txfifo/s | 由于FIFO錯(cuò)誤而導(dǎo)致的發(fā)送幀丟棄率 |
當(dāng) rxdrop/s
和 txdrop/s
存在數(shù)據(jù)時(shí),可以適當(dāng)調(diào)整上面的內(nèi)核緩沖內(nèi)核參數(shù)
需要注意的是計(jì)算大小的時(shí)候,需要使用 當(dāng)前大小,乘以頁數(shù),得到 KB 在 除以 1024 得到 MB。
┌──[root@liruilongs.github.io]-[~]
└─$bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.42012 * 4
168048
(interrupt) Exiting bc.
┌──[root@liruilongs.github.io]-[~]
└─$bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
168048/1024
164
^C
(interrupt) Exiting bc.
Socket 級別內(nèi)核參數(shù)限制
net.core.rmem_max,net.core.wmem_max
socket接受
和發(fā)送
數(shù)據(jù)的緩存的最大值
,單位為 bytes`` 字節(jié),也存在
net.core.rmem_default和
net.core.rmem_min`
┌──[root@liruilongs.github.io]-[~]
└─$cat /proc/sys/net/core/{rmem_max,wmem_max}
212992 #208K212992
┌──[root@liruilongs.github.io]-[~]
└─$
net.core.rmem_max
:該參數(shù)定義了套接字接收緩沖區(qū)
的最大大小。用于存儲(chǔ)從網(wǎng)絡(luò)接收到的數(shù)據(jù)
,等待應(yīng)用程序讀取。較大的接收緩沖區(qū)可以提高網(wǎng)絡(luò)吞吐量
和應(yīng)用程序的性能,尤其對于高速網(wǎng)絡(luò)或大量數(shù)據(jù)傳輸
的場景。
net.core.wmem_max
:該參數(shù)定義了套接字發(fā)送緩沖區(qū)
的最大大小。用于存儲(chǔ)應(yīng)用程序要發(fā)送到網(wǎng)絡(luò)的數(shù)據(jù),等待發(fā)送到網(wǎng)絡(luò)。較大的發(fā)送緩沖區(qū)可以提供更好的網(wǎng)絡(luò)發(fā)送性能
,尤其在高負(fù)載或延遲網(wǎng)絡(luò)
環(huán)境下。
這組內(nèi)核參數(shù)的優(yōu)化往往結(jié)合 BDP
來調(diào)整,等于或者大于 BDP 的值
,關(guān)于 BDP,下文我們會(huì)講。
在 通過 ifconfig
查看系統(tǒng)中所有網(wǎng)絡(luò)設(shè)備的基本性能統(tǒng)計(jì)信息。
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ifconfig ens32
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.26.81 netmask 255.255.255.0 broadcast 192.168.26.255inet6 fe80::20c:29ff:fead:e393 prefixlen 64 scopeid 0x20<link>ether 00:0c:29:ad:e3:93 txqueuelen 1000 (Ethernet)RX packets 507331 bytes 69923393 (66.6 MiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 556567 bytes 308574743 (294.2 MiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
關(guān)于部分參數(shù)的說明
列 | 說明 |
---|---|
RX packets | 設(shè)備已接收的數(shù)據(jù)包數(shù) |
TX packets | 設(shè)備已發(fā)送的數(shù)據(jù)包數(shù) |
errors | 發(fā)送或接收時(shí)的錯(cuò)誤數(shù) |
dropped | 發(fā)送或接收時(shí)丟棄的數(shù)據(jù)包數(shù) |
overruns | 網(wǎng)絡(luò)設(shè)備沒有足夠的緩沖區(qū)來發(fā)送或接收一個(gè)數(shù)據(jù)包的次數(shù) |
frame | 底層以太網(wǎng)幀錯(cuò)誤的數(shù)量 |
carrier | 由于鏈路介質(zhì)故障(如故障電纜)而丟棄的數(shù)據(jù)包數(shù)量 |
如果 overruns
存在值,可能需要調(diào)整上面的內(nèi)核參數(shù),適當(dāng)增大。
TCP 級別內(nèi)核參數(shù)
net.ipv4.tcp_rmem,net.ipv4.tcp_wmem
net.ipv4.tcp_rmem
和 net.ipv4.tcp_wmem
用于配置 TCP 套接字的接收緩沖區(qū)和發(fā)送緩沖區(qū)
的大小
。
┌──[root@liruilongs.github.io]-[~]
└─$cat /proc/sys/net/ipv4/tcp_rmem
4096 87380 6291456 # 4K 85K 6144K
┌──[root@liruilongs.github.io]-[~]
└─$cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4194304
net.ipv4.tcp_rmem
:配置 TCP 套接字接收緩沖區(qū)的大小。包含三個(gè)整數(shù)的列表,表示 最小、默認(rèn)和最大(以字節(jié)為單位)
。TCP 接收緩沖區(qū)用于存儲(chǔ)從網(wǎng)絡(luò)接收到的數(shù)據(jù)
,等待應(yīng)用程序讀取。
net.ipv4.tcp_wmem
:配置 TCP 套接字發(fā)送緩沖區(qū)的大小。同樣,也是包含三個(gè)整數(shù)的列表,表示最小、默認(rèn)和最大(以字節(jié)為單位)。TCP 發(fā)送緩沖區(qū)用于存儲(chǔ)應(yīng)用程序要發(fā)送到網(wǎng)絡(luò)的數(shù)據(jù)
,等待發(fā)送到網(wǎng)絡(luò)。
開啟一個(gè)sokcet
,內(nèi)核會(huì)在 min(第一列)
和 max(第三列)
之間自動(dòng)設(shè)置一個(gè) default(第二列)值
TCP 緩沖區(qū)
的大小應(yīng)根據(jù)系統(tǒng)和網(wǎng)絡(luò)的需求進(jìn)行調(diào)整。較大的緩沖區(qū)可以提高網(wǎng)絡(luò)性能
,特別是在高負(fù)載或高延遲
的網(wǎng)絡(luò)環(huán)境中。但是,過大的緩沖區(qū)可能會(huì)導(dǎo)致內(nèi)存占用增加或延遲
問題。
這兩個(gè)參數(shù)的調(diào)優(yōu)同樣參考 `BDP`` 來進(jìn)行優(yōu)化
BDP
可以驗(yàn)證緩存大小
是否合適,如何計(jì)算最大吞吐量時(shí)需要多少 緩存 呢?
BDP 是什么
round trip time(rtt 往返延遲時(shí)間)
本地發(fā)送數(shù)據(jù)包到遠(yuǎn)程,并從遠(yuǎn)程返回的時(shí)間叫 RTT
!
使用 ping 命令可以查看平均往返延遲時(shí)間
Linux
┌──[root@liruilongs.github.io]-[~]
└─$ ping -c 4 www.baidu.com
PING www.baidu.com (220.181.38.149) 56(84) bytes of data.
64 bytes from 220.181.38.149 (220.181.38.149): icmp_seq=1 ttl=128 time=14.5 ms
64 bytes from 220.181.38.149 (220.181.38.149): icmp_seq=2 ttl=128 time=15.0 ms
64 bytes from 220.181.38.149 (220.181.38.149): icmp_seq=3 ttl=128 time=14.3 ms
64 bytes from 220.181.38.149 (220.181.38.149): icmp_seq=4 ttl=128 time=14.1 ms--- www.baidu.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 4044ms
rtt min/avg/max/mdev = 14.190/14.522/15.002/0.344 ms
┌──[root@liruilongs.github.io]-[~]
└─$
最后一行可以看到,連接百度有 14 ms
的 RTT
時(shí)間,最后的輸出結(jié)果中可以看到結(jié)果信息,假設(shè)帶寬為 千兆帶寬,1000Mbps
,即 1Gb/s
,假設(shè)我們使用的是 千兆網(wǎng)卡
rtt min/avg/max/mdev = 14.190/14.522/15.002/0.344 ms
1Gb/s * 14.522ms
:帶寬
乘以往返時(shí)間(RTT)
可以用來估算網(wǎng)絡(luò)傳輸?shù)耐笛舆t
(Round-Trip Time Delay)。
將速度單位轉(zhuǎn)換為比特每秒
(b/s):1 Gb/s = 1,000,000,000 b/s
將時(shí)間單位轉(zhuǎn)換為秒
:14.522 ms = 14.522 * 0.001 s = 0.014522 s。
。
現(xiàn)在,我們可以計(jì)算表達(dá)式:1,000,000,000 b/s * 0.014522 s = 14,522,000 b
將比特轉(zhuǎn)換為字節(jié)
: 14,522,000 bit = 14,522,000 bit / 8 byte = 1,815,250 byte。(1 字節(jié)(byte)等于 8 位 (bit),將 14,52 2,000 比特除以 8 以獲得字節(jié)數(shù)。 因此,結(jié)果是 1,815,250 字節(jié)。
將字節(jié)轉(zhuǎn)換為 KiB(二進(jìn)制制式的千字節(jié))
,需要除以 1024:
1,815,250字節(jié) / 1024 = 1,772.705 千字節(jié)(KiB) / 1024 = 1.731 兆字節(jié)(MiB)=1,733.0625兆字節(jié) / 1024 = 0.00169千兆字節(jié)(GiB)
那么發(fā)送一個(gè)數(shù)據(jù)包等待回應(yīng)的時(shí)間是 0.014522 s
秒,實(shí)際上如何沒有這個(gè)延遲,這個(gè)時(shí)間段可以發(fā)送 1.731 MiB
的數(shù)據(jù),這個(gè)概念被稱為時(shí)延帶寬乘積(Bandwidth Delay Product,BDP)
互聯(lián)網(wǎng)的 rtt
值一般會(huì)比較大,rtt 值,即往返延遲越低,BDP 的值就越低
。
如果 BDP(時(shí)延帶寬乘積)大于64KiB(64千字節(jié))
,則在 TCP 連接中建議啟用TCP窗口縮放(TCP window scaling)
。TCP 窗口縮放是一種機(jī)制,用于擴(kuò)大TCP連接中的傳輸窗口大小
,以適應(yīng)高帶寬
和高延遲
的網(wǎng)絡(luò)環(huán)境。
設(shè)置 tcp_window_scaling 的值為 1
┌──[root@liruilongs.github.io]-[~]
└─$cat /proc/sys/net/ipv4/tcp_window_scaling
1
┌──[root@liruilongs.github.io]-[~]
└─$
如果一個(gè)系統(tǒng)需要處理多個(gè)并發(fā)連接
,則每個(gè)socket 緩存(rmem、wmem等)
的大小只要可以處理單個(gè)socket
的BDP容量
即可。
一般幾百KiB
基本夠用,但默認(rèn)的208KiB
有點(diǎn)小!當(dāng)然緩存區(qū)也不是越大越好
過多的緩存數(shù)據(jù)包
導(dǎo)致了數(shù)據(jù)包的延遲
,延遲抖動(dòng)
和降低
了網(wǎng)絡(luò)的總的通吐量
的現(xiàn)象
對于一個(gè)速度很快的網(wǎng)絡(luò)而言,如果配置一個(gè)過大的緩存區(qū),也可能導(dǎo)致及時(shí)通訊服務(wù)類的應(yīng)用體驗(yàn)很差。
根據(jù) BPD 配置網(wǎng)絡(luò)調(diào)優(yōu)參數(shù)
下面為在 window 機(jī)器上 ping 谷歌 DNS ,可以看到 有 169 ms
的 RTT
PS W:\Downloads> ping 8.8.8.8正在 Ping 8.8.8.8 具有 32 字節(jié)的數(shù)據(jù):
來自 8.8.8.8 的回復(fù): 字節(jié)=32 時(shí)間=168ms TTL=109
來自 8.8.8.8 的回復(fù): 字節(jié)=32 時(shí)間=169ms TTL=109
來自 8.8.8.8 的回復(fù): 字節(jié)=32 時(shí)間=169ms TTL=109
來自 8.8.8.8 的回復(fù): 字節(jié)=32 時(shí)間=169ms TTL=1098.8.8.8 的 Ping 統(tǒng)計(jì)信息:數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計(jì)時(shí)間(以毫秒為單位):最短 = 168ms,最長 = 169ms,平均 = 168ms
PS W:\Downloads>
假設(shè)當(dāng)前為百兆帶寬,計(jì)算 BDP :100 Megabits/s *? 0.169?s *? 1/8 Byte/bits? =? =100,000,000 bits/s * 0.169 s * 0.125 Byte/bit = 2,112,500 Bytes
添加 TCP 的讀取緩存相關(guān)內(nèi)核參數(shù)配置
備份當(dāng)前內(nèi)核參數(shù)
┌──[root@liruilongs.github.io]-[~]
└─$sysctl -a | grep rmem
net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.ipv4.tcp_rmem = 4096 87380 6291456
net.ipv4.udp_rmem_min = 4096
┌──[root@liruilongs.github.io]-[~]
└─$sysctl -a | grep rmem >> /etc/sysctl.conf
┌──[root@liruilongs.github.io]-[~]
└─$cat /etc/sysctl.conf
net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.ipv4.tcp_rmem = 4096 87380 6291456
net.ipv4.udp_rmem_min = 4096
┌──[root@liruilongs.github.io]-[~]
└─$cp /etc/sysctl.conf /root/
配置調(diào)優(yōu)后的內(nèi)核參數(shù)
修改設(shè)置(socket max最大值等于剛才計(jì)算的BDP的值,默認(rèn)值設(shè)置為最大值的一半:
┌──[root@liruilongs.github.io]-[~]
└─$vim /etc/sysctl.conf
┌──[root@liruilongs.github.io]-[~]
└─$sysctl -p
net.core.rmem_max = 2112500
net.ipv4.tcp_rmem = 4096 1056250 2112500
┌──[root@liruilongs.github.io]-[~]
└─$
碎片緩沖區(qū)參數(shù)
碎片緩存區(qū)
相關(guān)內(nèi)核參數(shù)在一些分片重組丟包
的場景需要優(yōu)化
當(dāng)前系統(tǒng)的默認(rèn)參數(shù)
┌──[root@vms100.liruilongs.github.io]-[~]
└─$sysctl -a | grep ipfrag
net.ipv4.ipfrag_high_thresh = 4194304
net.ipv4.ipfrag_low_thresh = 3145728
net.ipv4.ipfrag_max_dist = 64
net.ipv4.ipfrag_secret_interval = 0
net.ipv4.ipfrag_time = 30
┌──[root@vms100.liruilongs.github.io]-[~]
└─$
net.ipv4.ipfrag_high_thresh
設(shè)置了碎片緩沖區(qū)的高水位線為 4194304 字節(jié)(4 MB)。當(dāng)碎片緩沖區(qū)的使用率超過該閾值時(shí),內(nèi)核會(huì)開始丟棄新到達(dá)的碎片。
net.ipv4.ipfrag_low_thresh
設(shè)置了碎片緩沖區(qū)的低水位線為 3145728 字節(jié)(3 MB)。當(dāng)碎片緩沖區(qū)的使用率低于該閾值時(shí),內(nèi)核會(huì)停止丟棄新到達(dá)的碎片。
net.ipv4.ipfrag_max_dist
是一個(gè)用于限制數(shù)據(jù)包分片重組的內(nèi)核參數(shù)。它定義了分片偏移(fragment offset)之間的最大允許間隔。當(dāng)分片之間的偏移超過此閾值時(shí),內(nèi)核會(huì)丟棄分片并阻止重組,以防止可能的攻擊和資源耗盡。
net.ipv4.ipfrag_secret_interval
設(shè)置了碎片緩沖區(qū)的密鑰更新間隔為 0,表示不進(jìn)行密鑰更新。
net.ipv4.ipfrag_time
設(shè)置了碎片在緩沖區(qū)中保持的時(shí)間為 30 秒。超過該時(shí)間的碎片將被丟棄。
超時(shí)
在網(wǎng)絡(luò)通信過程中,有601個(gè)碎片在超時(shí)后被丟棄了
netstat -s|grep timeout
601 fragments dropped after timeout
通常發(fā)生在碎片重組過程中,當(dāng)某個(gè)碎片的到達(dá)時(shí)間超過了一定的時(shí)間限制(通常是根據(jù) net.ipv4.ipfrag_time
參數(shù)設(shè)置的)而沒有完全到達(dá)時(shí),內(nèi)核會(huì)丟棄這個(gè)碎片以避免無限等待。
解決方法:調(diào)整超時(shí)時(shí)間
net.ipv4.ipfrag_time = 30
sysctl -w net.ipv4.ipfrag_time=60
frag_high_thresh, 分片的內(nèi)存超過一定閾值會(huì)導(dǎo)致系統(tǒng)安全檢查丟包
netstat -s|grep reassembles
8094 packet reassembles failed
有8094個(gè)數(shù)據(jù)包的重組失敗了。這通常發(fā)生在數(shù)據(jù)包分片(fragmentation)和重組(reassembly)的過程中。
增加碎片緩沖區(qū)
的大小可以提供更多的空間來緩存和重組分片。通過調(diào)整 net.ipv4.ipfrag_high_thresh
和 net.ipv4.ipfrag_low_thresh
參數(shù)的值來增加緩沖區(qū)的大小。
其他網(wǎng)絡(luò)相關(guān)內(nèi)核參數(shù)
常用其他網(wǎng)絡(luò)相關(guān)內(nèi)核參數(shù)(需要修改):
┌──[root@liruilongs.github.io]-[~]
└─$ cat /proc/sys/net/ipv4/tcp_syn_retries # 建立TCP連接時(shí),內(nèi)核最大嘗試幾次syn連接,建議改為 3次
6
┌──[root@liruilongs.github.io]-[~]
└─$ cat /proc/sys/net/ipv4/tcp_synack_retries # 建立TCP連接時(shí),內(nèi)核最大嘗試幾次synack連接,建議改為 3 次
5
┌──[root@liruilongs.github.io]-[~]
└─$ cat /proc/sys/net/ipv4/tcp_tw_reuse # (允許將TIME-WAIT釋放出來,重新用于新的TCP連接,默認(rèn)值為0關(guān)閉狀態(tài))
2
┌──[root@liruilongs.github.io]-[~]
└─$ cat /proc/sys/net/ipv4/tcp_keepalive_time # 距離最后一次傳輸數(shù)據(jù)后多久,計(jì)算機(jī)發(fā)送keepalive探測包,最大保持連接秒數(shù)
7200
┌──[root@liruilongs.github.io]-[~]
└─$ cat /proc/sys/net/ipv4/tcp_fin_timeout # TCP連接關(guān)閉時(shí)等待FIN包的超時(shí)時(shí)間,當(dāng)前設(shè)置為60秒,修改后可以快速釋放wait-2的連接
60
┌──[root@liruilongs.github.io]-[~]
└─$ cat /proc/sys/net/ipv4/tcp_syncookies # 是否啟用TCP SYN cookies,當(dāng)前設(shè)置為1(啟用),防止Dos攻擊
1
┌──[root@liruilongs.github.io]-[~]
└─$ cat /proc/sys/net/ipv4/tcp_window_scaling # 是否啟用TCP窗口縮放,當(dāng)前設(shè)置為1(啟用)(窗口擴(kuò)大選項(xiàng)使TCP的窗口定義從16位增加到32位,更大的窗口大小,該參數(shù)的值是布爾值,0關(guān)或1開)TCP窗口主要用來控制流速率
1
┌──[root@liruilongs.github.io]-[~]
└─$ cat /proc/sys/net/ipv4/ip_local_port_range # TCP或UDP可以選擇本地的什么端口,連接遠(yuǎn)程的目標(biāo)端口,當(dāng)前設(shè)置為32768到60999
32768 60999
上面的配置修改都是臨時(shí)操作,內(nèi)核參數(shù)的永久修改需要 寫在配置文件 /etc/sysctl.conf
開啟巨幀
網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)包一般包含:包頭和數(shù)據(jù)載荷,一個(gè)典型的 TCP/IP 數(shù)據(jù)包頭會(huì)包含以太網(wǎng)頭部信息,IP 頭部信息和 TCP 頭部信息。
有這些報(bào)頭都包含在網(wǎng)絡(luò)上使用的最大傳輸單元(MTU)中,單個(gè)數(shù)據(jù)包的最大大小。
例如,使用 TCP 連接使用 52 個(gè)字節(jié)的協(xié)議頭。默認(rèn) MTU 為 1500 字節(jié),這幾乎占開銷損失的總?cè)萘康?3.5%。
有一種辦法是改變通信協(xié)議,比如將 TCP 改為 UDP,頭部信息就會(huì)從 52 字節(jié)變成 28 字節(jié)(對于 1500 數(shù)據(jù)包而言,1.9%的開銷),但是 UDP 不一定適合所有業(yè)務(wù)。
另一個(gè)方法是增加 MTU 的大小,將 MTU 修改為超過標(biāo)準(zhǔn)的 1500 字節(jié),被稱為巨幀(Jumbo Frames)。修改巨幀需要所有硬件設(shè)備都支持該功能。
我們可以使用 nmcli 修改網(wǎng)卡的 MTU 大小(下面的例子將 ens33 網(wǎng)卡的 MTU 修改為 9000)
nmcli con modify ens33 802-3-ethernet.mtu 9000
如果需要修改 MTU 大小,則需要先確認(rèn)以下這些設(shè)備是否支持巨幀(但不限于這些設(shè)備):
- 網(wǎng)卡
- 交換機(jī)
- 路由器
一般官方推薦定義的巨幀 MTU 為 9000bytes(字節(jié)),但是也有設(shè)備支持更大的幀數(shù)據(jù)。
加大幀大小的好處在于,減少了網(wǎng)絡(luò)中數(shù)據(jù)包的個(gè)數(shù),減輕了網(wǎng)絡(luò)設(shè)備處理包頭的額外開銷(可以顯著提升性能)。
但缺點(diǎn)是,巨幀至今沒有標(biāo)準(zhǔn)化,如果使用不同的 MTU 可能會(huì)導(dǎo)致有些設(shè)備不兼容,而傳統(tǒng)的以太網(wǎng) MTU 是所有設(shè)備都兼容的。
博文部分內(nèi)容參考
? 文中涉及參考鏈接內(nèi)容版權(quán)歸原作者所有,如有侵權(quán)請告知 😃
<Rh442 授課筆記>
https://zhuanlan.zhihu.com/p/502027581?utm_id=0
? 2018-2023 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)