JMeter測試TCP/IP Socket應用的性能

摘要

本文描述瞭如何利用JMeter來測試TCP/IP Socket應用的性能。文章先對Socket做了一點簡單介紹,而後提供並解釋了兩個樣例Socket應用,最後介紹如何利用JMeter來對它們進行測試。javascript

Socket簡介

基於TCP/IP協議的Socket(套接字)應用是構成如今互聯網的基礎,HTTP協議就是創建在端口80上的套接字應用。如今仍是有不少應用直接創建套接字,接受客戶端的請求並進行相應的業務處理,那麼隨着業務量的增長,如何對基於套接字的應用進行性能測試呢?本文將介紹如何利用開源的JMeter對基於TCP/IP協議的套接字應用進行性能測試。css

套接字應用通常至少須要一對套接字,其中一個運行於客戶端,稱爲ClientSocket ,另外一個運行於服務器端,稱爲ServerSocket 。java

服務器和客戶端套接字之間的鏈接過程分爲三個步驟:服務器監聽,客戶端請求,鏈接確認。git

  1. 服務器監聽:服務器端套接字打開後處於等待鏈接的狀態,等待客戶端的鏈接請求
  2. 客戶端請求:指客戶端的套接字發出創建鏈接請求,要鏈接的目標是服務器端的套接字。客戶端的套接字在鏈接的時候須要指定服務器端套接字的地址和端口號,而後才能發出鏈接請求
  3. 鏈接確認:當服務器端套接字接收到客戶端套接字的鏈接請求時,就響應客戶端套接字的請求,處理完客戶端發出的數據後,返回給客戶端處理結果。

服務器端通常經過多線程的方式來接受不一樣用戶發出的處理請求,所以同時能夠接受多個客戶端發出的處理請求。套接字應用中客戶端和服務器端之間溝通的數據格式根據應用的設計而定,能夠是可讀的文本格式,也能夠是二進制流的格式,對於這兩種不一樣的格式,JMeter有不一樣的處理方式。github

測試基於文本套接字應用

被測應用的源碼請參見這裏. 若是想運行該程序,請點擊該連接下載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鏈接到服務器端的套接字應用,雙方就能夠直接進行通訊了。apache

服務器端:接收到請求並返回客戶端「Echo: hello」字符串。服務器

 

 
服務器端控制檯運行截屏

 

客戶端經過telnet鏈接到服務器端的4700端口,並輸入hello多線程

 

 
客戶端控制檯運行截屏


使用JMeter對套接字進行測試,有如下的選項能夠作控制:socket

  1. TCPClient classname: 缺省的org.apache.jmeter.protocol.tcp.sampler。TCPClientImpl, TCPClient只能實現基於文本格式的套接字應用的測試。隨JMeter提供的還有另外的兩個實現,分別是BinaryTCPClientImpl和LengthPrefixedBinaryTCPClientImpl,用於處理二進制格式的數據,後文將對這兩個作詳細的介紹。
  2. ServerName or IP: 套接字服務器應用的地址
  3. Port Number: 套接字服務器應用的端口
  4. Re-use connection: 若是選中,鏈接會一直處於打開狀態,不然讀取到數據以後就關閉
  5. Close connection: 若是選中,在TCP Sampler運行完畢以後就會被關閉
  6. SO_LINGER:該配置項用於控制在關閉鏈接以前是否要等待緩衝區中的數據發送完成。若是SO_LINGER選項指定了值,則在獲得關閉鏈接的請求以後還會等待指定的秒數以完成緩衝區中數據的發送,在指定的SO_LINGER秒數完成後,關閉鏈接。所以,若是你把該選項設置成0,那麼全部鏈接在收到關閉鏈接的時候都會當即關閉,避免產生不少處於TIME_WAIT狀態的套接字。
  7. End of line(EOL) byte value:判斷行結束的byte值,若是你指定的值大於127或者小於-128,則會跳過EOL檢測。好比服務器端返回的字符串都是以回車符結尾,那麼咱們能夠將該選項設置成10。
  8. Connect Timeout:與服務器套接字應用鏈接超時時間(毫秒)。
  9. Response Timeout:響應超時時間(毫秒),這個值的設置跟End of line(EOL) byte value有關係,若是End of line(EOL) byte value中的值設置不正確,會致使JMeter一直在等待沒法結束,可是若是指定了Response Timeout這個值的話,在到達這個值的時候就關閉鏈接。
  10. Set NoDelay:是否使用Nagle算法,是否須要使用該選項,須要跟實際的業務狀況結合。
  11. Text to Send:發送的文本,跟「CSV dataset config」一塊兒使用可以從文件中直接讀取。
  12. Username和Password:這兩個選項在TCP相關的Sampler中都未使用,請忽略這兩個選項。

針對咱們的樣例應用,咱們的配置以下所示,具體的含義在前面都已經有描述,在這裏再也不贅述。若是想增長壓力,只需調整ThreadGroup中的數目便可。

 
TCP鏈接配置截圖

測試基於二進制套接字應用

被測應用的源碼請參見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爲校驗和

 
二進制TCP鏈接配置截圖

另外針對該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插件。

相關文章
相關標籤/搜索