本文版權歸xmeter.net 所有。歡迎轉載,轉載請注明出處。
摘要
本文描述了如何利用JMeter來測試TCP/IP Socket應用的性能。文章先對Socket作了一點簡單介紹,然后提供并解釋了兩個樣例Socket應用,最后介紹如何利用JMeter來對它們進行測試。
Socket簡介
基于TCP/IP協議的Socket(套接字)應用是構成現在互聯網的基礎,HTTP協議就是建立在端口80上的套接字應用。現在還是有很多應用直接建立套接字,接受客戶端的請求并進行相應的業務處理,那么隨著業務量的增加,如何對基于套接字的應用進行性能測試呢?本文將介紹如何利用開源的JMeter對基于TCP/IP協議的套接字應用進行性能測試。
套接字應用一般至少需要一對套接字,其中一個運行于客戶端,稱為ClientSocket ,另一個運行于服務器端,稱為ServerSocket 。
服務器和客戶端套接字之間的連接過程分為三個步驟:服務器監聽,客戶端請求,連接確認。
- 服務器監聽:服務器端套接字打開后處于等待連接的狀態,等待客戶端的連接請求
- 客戶端請求:指客戶端的套接字發出建立連接請求,要連接的目標是服務器端的套接字。客戶端的套接字在連接的時候需要指定服務器端套接字的地址和端口號,然后才能發出連接請求
- 連接確認:當服務器端套接字接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,處理完客戶端發出的數據后,返回給客戶端處理結果。
服務器端一般通過多線程的方式來接受不同用戶發出的處理請求,因此同時可以接受多個客戶端發出的處理請求。套接字應用中客戶端和服務器端之間溝通的數據格式根據應用的設計而定,可以是可讀的文本格式,也可以是二進制流的格式,對于這兩種不同的格式,JMeter有不同的處理方式。
測試基于文本套接字應用
被測應用的源碼請參見這里. 如果想運行該程序,請點擊該鏈接下載socket_echo-0.0.1-SNAPSHOT.jar,并且在命令行下執行:
java -cp socket_echo-0.0.1-SNAPSHOT.jar net.xmeter.echo.TextServer
(請確保您的機器上已經安裝了Java)。 該程序會在4700端口建立一個ServerSocket,等待來自客戶端的請求,客戶端如果發送了一個字符串,服務器端返回“Echo: “ + 客戶端發送的字符串。如下圖所示,如果我們使用telnet連接到服務器端的套接字應用,雙方就可以直接進行通信了。
服務器端:接收到請求并返回客戶端“Echo: hello”字符串。
客戶端通過telnet連接到服務器端的4700端口,并輸入hello
使用JMeter對套接字進行測試,有以下的選項可以做控制:
- TCPClient classname: 缺省的org.apache.jmeter.protocol.tcp.sampler。TCPClientImpl, TCPClient只能實現基于文本格式的套接字應用的測試。隨JMeter提供的還有另外的兩個實現,分別是BinaryTCPClientImpl和LengthPrefixedBinaryTCPClientImpl,用于處理二進制格式的數據,后文將對這兩個做詳細的介紹。
- ServerName or IP: 套接字服務器應用的地址
- Port Number: 套接字服務器應用的端口
- Re-use connection: 如果選中,連接會一直處于打開狀態,否則讀取到數據之后就關閉
- Close connection: 如果選中,在TCP Sampler運行完畢之后就會被關閉
- SO_LINGER:該配置項用于控制在關閉連接之前是否要等待緩沖區中的數據發送完成。如果SO_LINGER選項指定了值,則在得到關閉連接的請求之后還會等待指定的秒數以完成緩沖區中數據的發送,在指定的SO_LINGER秒數完成后,關閉連接。因此,如果你把該選項設置成0,那么所有連接在收到關閉連接的時候都會立即關閉,避免產生很多處于TIME_WAIT狀態的套接字。
- End of line(EOL) byte value:判斷行結束的byte值,如果你指定的值大于127或者小于-128,則會跳過EOL檢測。比如服務器端返回的字符串都是以回車符結尾,那么我們可以將該選項設置成10。
- Connect Timeout:與服務器套接字應用連接超時時間(毫秒)。
- Response Timeout:響應超時時間(毫秒),這個值的設置跟End of line(EOL) byte value有關系,如果End of line(EOL) byte value中的值設置不正確,會導致JMeter一直在等待無法結束,但是如果指定了Response Timeout這個值的話,在到達這個值的時候就關閉連接。
- Set NoDelay:是否使用Nagle算法,是否需要使用該選項,需要跟實際的業務情況結合。
- Text to Send:發送的文本,跟“CSV dataset config”一起使用能夠從文件中直接讀取。
- Username和Password:這兩個選項在TCP相關的Sampler中都未使用,請忽略這兩個選項。
針對我們的樣例應用,我們的配置如下所示,具體的含義在前面都已經有描述,在這里不再贅述。如果想增加壓力,只需調整ThreadGroup中的數目即可。
測試基于二進制套接字應用
被測應用的源碼請參見BinaryServer.java。如果想運行該程序,請點擊該鏈接下載socket_echo-0.0.1-SNAPSHOT.jar,并且在命令行下執行:
java -cp socket_echo-0.0.1-SNAPSHOT.jar net.xmeter.echo.BinaryServer
該應用場景是服務器端的套接字應用在接受來自客戶端發送的物聯網數據的請求,并進行解析及處理(處理邏輯就是在控制臺上打印客戶端發送過來的值)。客戶端發送過來的值的格式如下:
byte[0]: 開始界定符,用于標識數據的開始,值為126,十六進制值為7E
byte[1]: 發送的數據條數,如果一次發送了溫度、光照強度和濕度3條數據,則該值為3
byte[2]: 數據1的類型,1為溫度,2為光照強度,3為濕度
byte[3]: 數據1的值
byte[4]: 數據2的類型,1為溫度,2為光照強度,3為濕度
byte[5]: 數據2的值
…
byte[last]: 校驗和
服務器套接字應用在完成處理后,返回給客戶端如下格式的值:
byte[0]: 開始界定符,用于標識數據的開始,值為126,十六進制值為7E
byte[1]: 返回碼,0為成功,1為失敗
byte[3]: 校驗和
byte[4]: 回車符作為結束符
JMeter測試腳本中與字符類型相同的在這里就不做解釋了,下面描述一下二進制格式測試的不同點:
1)因為現在需要發送的是二進制的數據,所以在“TCPClient classname” 字段中輸入的是 org.apache.jmeter.protocol.tcp.sampler.BinaryTCPClientImpl
2)End of line(eol),服務器端返回的是以回車符為結束的,因此這里輸入回車符的ascii碼值10,如果你的被測應用不是10結尾,請輸入別的值
3)Text to send:發送的數據7E0301010214031EC9,7E是開始界定符,03表示此次傳輸3條數據,第一條數據為溫度,值是0x01;第二條數據類型是光照強度,值為0x14;第三條數據為濕度,值為0x1E,C9為校驗和
另外針對該Sampler,腳本里還加了一個斷言,驗證返回的數據是否正確,可以看到對結果的驗證期望是7e00ff0a,其中7e是開始界定符,00是返回碼,ff是校驗和,0a是回車符。
運行成功的話,在服務器端套接字應用的控制臺上能看到下面的信息。
Find the start delimiter at 0.
Received data 1 for sensor temperature.
Received data 20 for sensor brightness.
Received data 30 for sensor humidity.
Correct data. Return with correct response code.
如果讀者測試的基于套接字的應用比較復雜,JMeter本身提供的Sampler不能處理,那么可能需要自己擴展TCP Sampler(一般可以通過繼承類org.apache.jmeter.protocol.tcp.sampler.TCPClient來實現)。JMeter提供了靈活的插件擴展機制,允許用戶實現一些比較個性化的需求。讀者可以參見我們寫的這篇文章來了解如何擴展JMeter插件。
大規模套接字應用的測試 - XMeter幫您提高效率,降低成本
單臺機器能夠模擬的套接字客戶端是有限的,如果針對大規模的套接字應用的測試,可能需要準備大量的測試機器對被測系統進行打壓,這個過程需要大量的準備機器環境,以及管理這些環境的工作,導致工作效率比較低、而且容易出錯。XMeter將這些過程遷移至云端,彈性伸縮管理這些壓力機,用戶只要關注測試腳本的實現過程,而無需關心這些測試環境的管理,從而大大降低了大規模性能測試的復雜度。另外XMeter提供了豐富的測試報告,讓性能問題一目了然。
關于我們
XMeter成立于2016年,核心團隊都來自于IBM,是一家領先技術的性能測試持續集成咨詢與服務提供商。我們致力于提供給客戶可靠,簡單,低成本的性能測試解決方案。