效能測試網路效能瓶頸分析
一、引出問題點:
在做效能測試中,談到網路問題時,其實,在沒有特別說明的情況下,我們一般講的都是HTTP協議下的網路瓶頸問題,那麼對於這個問題,我們如何來分析呢?
舉例說明:
計算機中的網路,跟我們現實生活中的交通網路,其實也是一個道理,可以類比。
例如:你從住的地方,到你公司上班,人的位置,在整個過程中發生了移動,就相當於我們網路中一個數據包進行了傳輸,我們可以這樣類比,來剖析下這個移動過程:
-
首先,住的地方是已知的,住的很豪華,有非常多的門,你要去上班,從任意一個門出來都可以,但是門再多,它也是有一定數量的。
-
從門出來,你就會想,用什麼樣的交通工具,如果使用4個輪子的車子,那接下來就會選擇道路,因為不同的道路,擁堵情況可能不一樣。
-
現在,你開車到了公司樓下,你又會選擇從哪個門進公司。如果時間緊,人又多,一窩蜂都擠到一個門,你小身板,可能就擠不進去,所以你可能會挑一個足夠寬讓你進去的門
接下來,我們根據這個過程,分析下,影響我們上班過程的瓶頸有哪些?
-
門很多,但是總有個數量,萬一門不夠,是不是就出不去了?所以,這個出口門,可能會是個瓶頸。
-
交通工具和道路。不同的交通工具,速度不一樣;道路等級、寬窄、流通量都會影響通行速度,都可能是瓶頸。
-
公司入口門,如果大家都在同一時間點從門口進來,是不是就會要排隊,或者進不來,那這個入口門,也可能會是瓶頸。
-
進入公司後,要進入辦公室,辦公室的門寬度,是不是也可能是個瓶頸。
總結: 現在,我們知道了影響我們上班是否遲會到的瓶頸了,其實,在我們網路效能分析中,也是類似的。用HTTP協議來規範網路通訊,用TCP\UDP進行資料傳輸,它就是我們上班的交通工具
TCP連線有四個組成元件:源地址、源埠、目的地址、目的埠。
(1)源地址:就是你自己機器的ip,相當於你住的地址,一般都是唯一的;
(2)源埠:就是發起通訊的埠,就是你從家裡出來的門,你發起一次通訊,就會要先找一個埠,開啟埠,從端口出去,然後關閉埠。
(3)目的地址:這個過程,作為常規的使用,完全沒有問題,所以平常大家都不關注這個。
(4)目的埠:但是,埠是很多,也耐不住你使勁的‘造’啊(就像你家很豪華,門再多,也耐不住你浪費啊。)
總結:在我們效能測試時,就是使勁的‘造’,會開啟大量的埠,處於佔用狀態,沒有獲得到埠的就出不去,從而就可能出現,埠不夠用的情況。
即:現在明白網路效能的第一個可能的瓶頸是什麼了吧!---> 埠不夠用!!!
二、源地址埠不夠用
大家在公司日常用的更多的電腦就是Windows,那windows的電腦埠有多少呢?
-
我們可以先簡單理解為埠總共有65535個,其中
-
0~1023(共1024個),為公認埠,緊密的繫結在一些特定服務上,如21埠就是FTP服務,80埠就是HTTP服務;
-
1024~49151(共48127個),為註冊埠,鬆散的綁定於一些服務,如8080埠常常就用於繫結tomcat服務;
-
49152~65535(共16384個),為動態或私有埠。
(1)看了這樣一組資料,知道在做效能測試時,你本機TCP通訊最多能消耗多少個埠了嗎?
即:實際上,一臺電腦TCP通訊埠應該是在16400+ 個,當然也不會超過太多。
(2)為什麼不是16384,而是這樣一個值呢?
即:因為‘註冊埠’中有部分埠,也會用於tcp通訊。所以在效能測試時,最大可用埠範圍會稍微大一點。
看到這,是不是就特別想知道怎麼檢視Windows系統中,TCP埠連線佔用情況呢?
Windows系統檢視當前TCP連線數:
netstat -ano | find "TCP" /i /c
# netstat 顯示協議統計資訊和當前TCP/IP網路連線情況
# -a 顯示所有連線和偵聽埠
# -n 以數字形式顯示地址和埠號
# -o 顯示擁有的與每個連線關聯的程序ID
# /i 指定搜尋不區分大小寫
# /c 對包含指定的資訊進行計數,並顯示總計
Linux 檢視當前tcp連線數的方法
netstat -ano |grep 'tcp' | wc -l
現在已經知道如何實時查看了,那實際執行效能測試,如果出現源地址埠不夠用,會出現什麼樣的問題表現呢?
Address already in use: connect
java.net.BindException: Address already in use: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75)
at ......
雖然出現Address already in use: connect這個問題,原因很多,但源地址埠不夠用,就是其中一個常見的原因
我們可以嘗試如下方法調優:
方法一:
如果是使用jmeter進行效能測試,出現上述報錯,可以直接去掉http取樣器的 【使用 KeepAlive】 複選勾。
方法二:
-
開啟系統的登錄檔-->找到 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]-->
-
看下右側的配置資訊-->有沒有MaxUserPort配置項,有-->則修改值為 65534(十進位制)-->確定
-
沒有-->則新增一個DWORD, name為MaxUserPort, value為 65534(十進位制)-->確定-->
-
重啟系統
可以參考地址:https://docs.microsoft.com/en-us/troubleshoot/windows-client/networking/connect-tcp-greater-than-5000-error-wsaenobufs-10055
完成這一步,我們已經知道,我們的系統當前埠可用範圍已經達到最大。
接下來,我們還需要知道,埠被使用後,如果我們能及時回收,再利用是不是能提高階口利用率,這樣是不是就變相增加了埠了呢?
所以,第二個調優方法就是,釋放、回收埠。
方法三:
-
開啟系統的登錄檔-->找到 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]-->
-
看下右側的配置資訊,有沒有 TcpTimedWaitDelay配置項有-->則修改值為 10(十進位制,10秒)-->確定
-
沒有-->則新增一個DWORD, name為TcpTimedWaitDelay, value為 30(十進位制)-->確定
-
重啟系統
可以參考地址:https://docs.microsoft.com/en-us/troubleshoot/windows-client/networking/tcpip-and-nbt-configuration-parameters
完成了這兩步,我們就已經完成了傳送方的網路調優。
******
第二段分析:現在,我們已經知道如何解決從家裡出來可能的問題了,接下來,就是開車,去上班。把車開出來,
先經過一段引路,然後才能進入主幹道,主幹道通行一段距離後,下主幹道,進入一段公司引路,再進入公司
******
其實,我們的網路資料傳輸,也可以這樣類比,網路資料包要通過網絡卡,使用網路傳輸介質(如網線)在網路中進行傳輸,進過多次週轉,找到目標伺服器,通過伺服器網絡卡,進入伺服器內部。
由此可以分析出:
-
傳送方的網絡卡速率有10m、百兆、G兆網絡卡,如果網絡卡不行,可能成為瓶頸。
-
傳輸介質,有線、無線,有線的介質(如雙絞線、同軸電纜、光纖)、路由的複雜度(如國內、國外)等等,都會影響傳輸速度,這個有可能成為瓶頸。
-
服務器接收資料的網絡卡速率,照樣也可能成為瓶頸
c:\>ping ke.qq.com
正在 Ping ke.qq.com [101.89.15.159] 具有 32 位元組的資料:
來自 101.89.15.159 的回覆: 位元組=32 時間=22ms TTL=54
來自 101.89.15.159 的回覆: 位元組=32 時間=23ms TTL=54
來自 101.89.15.159 的回覆: 位元組=32 時間=22ms TTL=54
來自 101.89.15.159 的回覆: 位元組=32 時間=23ms TTL=54
101.89.15.159 的 Ping 統計資訊:
資料包: 已傳送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒為單位):
最短 = 22ms,最長 = 23ms,平均 = 22ms
通過ping對方的域名或ip,在效能測試同時,網路傳輸時延以及丟包情況。丟包或時延比較嚴重,那麼說明網路已經阻塞,需要做上述瓶頸分析;如果沒有丟包,時延也很低,說明網路比較正常。
三、網路傳輸通道瓶頸
Ⅰ、檢視發起請求的機器網絡卡速率。如果是Windows10電腦,可以在 “網路連線” > 選中機器網絡卡,右鍵‘狀態’ > 檢視彈窗中的‘速度’
Ⅱ、 檢查網路傳輸路由,Windows下執行:
c:\>tracert -d ke.qq.com
通過最多 30 個躍點跟蹤
到 ke.qq.com [101.89.15.159] 的路由:
1 <1 毫秒 <1 毫秒 <1 毫秒 192.168.1.1
2 1 ms 1 ms 1 ms 175.8.48.1
3 5 ms 5 ms 5 ms 61.187.3.33
4 * * * 請求超時。
5 23 ms 23 ms 24 ms 202.97.19.141
6 24 ms 24 ms 24 ms 101.95.88.77
7 * * * 請求超時。
8 * * * 請求超時。
9 * * * 請求超時。
10 * * * 請求超時。
11 * * * 請求超時。
12 22 ms 22 ms 22 ms 101.89.15.159
跟蹤完成。
第1列,表示路由節點數量;
第2~4列,表示連線到每個路由節點的速度、返回速度、多次連線反饋的平均值;
最後的ip,代表路由地址。
從這個就能看出在哪個節點時間長,可能有優化空間。
Ⅲ、資料傳輸到伺服器了,現在要檢視伺服器的網絡卡資訊。
[root@localhost ~]# ethtool ens33 | grep "Speed"
Speed: 100Mb/s
# ens33 為網絡卡名稱
通過這個命令,我們可以看到ens33這個網絡卡,目前設定的速度為100Mb/s,這個已經非常大了,如果這個值過低,可能就需要改大,可以執行:
ethtool -s ens33 speed 1000
# 將網絡卡的速度設定為 1000Mb/s
現在我們知道如何檢視確認我們資料傳輸通道的問題了。
顯然,我們對於這個環節出現瓶頸,辦法不是很多。就像我們上班的路,我們能在引路上想些辦法,規劃好行車路線,但是我們對於主幹道,幾乎無能為力。
好了,現在網路資料包,已經到達伺服器了。伺服器,現在一般情況下,都是linux為主。所以,接下來,就要看linux中可能的瓶頸了
四、目的地址埠瓶頸
******
其實我們的請求在伺服器上,就是類似這樣,非常多的請求來到伺服器,最後都是通過某個埠,或者幾個埠真正獲取響應資料。
首先,我們得知道,一臺機器,再強,也只能接收一定量的請求,這個數量是有最大值的,我們可以通過:
******
linux機器上檢視允許的連線配置
[root@localhost ~]# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7197
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7197
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
如果覺得這個配置的'max user process' 和 'open files'太小,可以修改 /etc/security/limits.conf
[root@localhost ~]# vim /etc/security/limits.conf
# 新增如下
your_account soft nproc 32768
your_account hard nproc 32768
root soft nproc 32768
root hard nproc 32768
your_account soft nofile 16000
your_account hard nofile 16000
root soft nofile 16000
root hard nofile 16000
修改完後, max user processes 就會改成32768, open files 值變更為 16000
做完這波操作,就相當於你對公司的入口門進行了設定,根據你的需要調整了門的寬度。
五、伺服器內部埠瓶頸
首先我們可以檢視下你當前服務的埠連線數量:
netstat -ane |grep '埠' | grep ESTABLISHED |wc -l
這個命令執行完後,你會獲得一個數值,這個數量到達一定的峰值之後,就不會再增長了,當你測試結束的時候,這個峰值就會逐步降低。
其實,這就是我們服務的連線數量,而這個數量,是可以配置的。
如果你的服務是tomat,可以在tomcat的conten.xml中,配置
<Executor name="tomcatThreadPool" namePrefix ="catalina-exec-" maxThreads="150" minSpareThreads="4" />
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" acceptCount="1000" />
<!---
name:該執行緒池的標記
maxThreads:執行緒池中最大活躍執行緒數,預設值200(Tomcat7和8都是)
minSpareThreads:執行緒池中保持的最小執行緒數,最小值是25
maxIdleTime:執行緒空閒的最大時間,當空閒超過該值時關閉執行緒(除非執行緒數小於minSpareThreads),單位是ms,預設值60000(1分鐘)
daemon:是否後臺執行緒,預設值true
threadPriority:執行緒優先順序,預設值5
namePrefix:執行緒名字的字首,執行緒池中執行緒名字為:namePrefix+執行緒編號
--->
修改maxThreads的值,就是在修改我們的最大峰值。
注意:maxThreads 不是無限大的, 越大-->相應的消耗的資源也會越多。