本文版權歸xmeter.net 全部。歡迎轉載,轉載請註明出處。html
JMeter自己提供了插件機制,容許第三方擴展JMeter以支持JMeter不支持的協議的測試。本文以擴展一個簡單的Apache Kafka producer sampler爲例描述瞭如何對JMeter進行擴展,方便地實現對新協議的支持。java
Apache Kafka是由Apache軟件基金會開發的一個開源消息系統項目。Kafka最初是由LinkedIn開發,並於2011年初開源。2012年10月從Apache孵化器畢業。該項目的目標是爲處理實時數據提供一個統1、高通量、低等待的平臺。git
以下圖所示,Kafka的producer(數據生產者)經過Socket向Kafka集羣上配置好的主題(topic)發送數據,consumer(數據消費者)在另一端消費由生產者那邊產生的數據,並進行業務的處理。Kafka做爲一個優秀的消息處理系統,在集羣配置,主題管理等方面有不少須要深刻理解和優化等地方,本文的重點是JMeter的擴展,以Kafka的生產者爲例來描述如何利用JMeter來模擬大量的生產者的調用,更多關於Kafka的細節請參考它的官方文檔
github
擴展實現JMeter插件以前,須要先考慮清楚哪些選項須要暴露給測試人員。就像HTTP測試中,須要讓用戶輸入服務器地址,端口號,路徑等,同線程組裏的鏈接是否共用等,若是提供是否共用鏈接這種選項的話,也須要在界面中體現,固然實現插件的時候處理鏈接的代碼也會有所不一樣。apache
往Kafka上發送消息的時候,須要提供一些基本配置信息(實際Kafka的生產者配置不止這些),若是讀者對下面所說的內容不瞭解也沒關係,只須要理解準備這些的目的是爲了將這些配置信息提供給Kafka測試人員,在開始測試以前能夠針對被測系統進行配置。服務器
下圖是本文最終完成的JMeter Kafka插件的截圖,測試開始以前須要輸入上文所列的信息。網絡
JMeter插件實現是標準的Java代碼,打開Eclipse(做者使用的是4.5.2),新建一個Maven項目。咱們的項目中須要引用到JMeter自己提供的一些庫,包括ApacheJMeter_core和ApacheJmeter_java,而且對JMeter的版本依賴是3.0。另外,還須要對Kafka的類庫也須要引入,pom.xml中依賴部分的代碼以下。併發
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jmeter-version>3.0</jmeter-version> </properties> <dependencies> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_core</artifactId> <version>${jmeter-version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_java</artifactId> <version>${jmeter-version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka_2.9.2</artifactId> <version>0.8.1.1</version> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
工程建立完畢以後,開始編寫代碼來實現插件。框架
JMeter的插件機制會在$JMETER_HOME/lib/ext目錄下去動態加載符合指定條件的JAR包,並在JMeter中顯示出來。好比要擴展UI的話,擴展的Java類的包名必須是」.gui.」,一樣的擴展函數的Java類的包名必須是」.function.」.maven
新建一個類,org.apache.jmeter.protocol.kafka.control.gui.KafkaSamplerUI,並指定其父類爲AbstractSamplerGui。該類須要實現如下的功能:
1)界面佈局與控件。JMeter的界面是標準的Swing,因此裏面的控件和佈局都是標準的Swing寫法。
2)界面與Sampler之間的數據交換。Sampler在JMeter中繼承的是TestElement,用戶輸入的數據都是保存在Sampler中的,所以能夠認爲這個是界面的模型。界面與模型(Sampler)之間的數據交換須要實現父類的下面幾個方法,
public void configure(TestElement el)
該方法用於把Sampler中的數據加載到界面中。在實現本身的邏輯以前,先調用一下父類的方法super.configure(el),這樣能夠確保框架自動爲你加載一些缺省數據,好比Sampler的名字。
public void modifyTestElement(TestElement e)
這個方法用於把界面的數據移到Sampler中,恰好與上面的方法相反。在調用本身的實現方法以前,請先調用一下super.configureTestElement(e),這個會幫助移到一些缺省的數據。
public TestElement createTestElement()
該方法建立一個新的Sampler,而後將界面中的數據設置到這個新的Sampler實例中。
public void clearGui()
該方法會在reset新界面的時候調用,這裏能夠填入界面控件中須要顯示的一些缺省的值。
在本文的實現中,分別實現上面的那些方法,包括顯示5個控件(4個控制參數的控件在一個panel裏,發送的消息的控件在另一個panel裏),以及另外的幾個方法用於和Sampler之間的數據交換等。完整的代碼請參見這裏。
新建一個Sampler,org.apache.jmeter.protocol.kafka.sampler.KafkaSampler,並指定其父類爲AbstractSampler。該類須要實現如下的功能:
1)增長一些getter/setter方法,這些方法用於與UI之間的數據交換,這些數據在用戶保存/打開腳本的時候將被自動序列化/反序列化。
2)實現sample方法:
public SampleResult sample(Entry entry)
該方法是JMeter實現對目標系統發起請求實際工做的地方。主要的工做是記錄請求處理時間,對返回結果進行處理和判斷,並根據處理結果返回SampleResult,該SampleResult中須要指定返回的內容是否成功,以及消息等。該方法的基本實現框架以下所示:
public SampleResult sample(Entry entry) { SampleResult result = new SampleResult(); result.setSampleLabel(getName()); try { result.sampleStart(); //對目標系統發出測試請求 result.sampleEnd(); result.setSuccessful(true); result.setResponseCodeOK(); } catch (Exception e) { result.sampleEnd(); // stop stopwatch result.setSuccessful(false); result.setResponseMessage("Exception: " + e); // get stack trace as a String to return as document data java.io.StringWriter stringWriter = new java.io.StringWriter(); e.printStackTrace(new java.io.PrintWriter(stringWriter)); result.setResponseData(stringWriter.toString(), null); result.setDataType(org.apache.jmeter.samplers.SampleResult.TEXT); result.setResponseCode("FAILED"); } return result; }
本文的實現中,生成一個Kafka的Producer對象,並將用戶界面裏指定的信息發送到Kafka服務器上。完整的代碼請參見這裏。
打包過程與普通的Maven項目類似,可是須要注意的是本插件須要把Kafka相關的依賴庫文件也一併打入,不然還須要單獨準備所依賴的JAR包。所以在pom.xml中加入下面的build插件。右擊工程 》Run As 》Maven install,運行成功後,在工程的target目錄下會生成一個kafka_jmeter-jar-with-dependencies.jar,這個就是咱們打好的插件。
<build> <finalName>${project.artifactId}</finalName> <defaultGoal>install</defaultGoal> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>assemble-all</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
插件開發完成後,將kafka_jmeter-jar-with-dependencies.jar拷貝到$JMETER_HOME/lib/ext目錄下,若是以前已經打開了JMeter,則須要將JMeter關閉重啓。
新建一個測試腳本,加入一個線程組,而後添加一個Sampler,若是運行正常,在子菜單中應該能看到咱們擴展出來的「Kafka Sampler」。
修改一下線程組裏的線程數,則能實現多虛擬用戶的併發測試了。下圖是「查看結果樹」裏面顯示的內容。
下圖是Kafka的消費者端,能看到相關的消息已經發送成功。
如本文所示,若是經過比較「標準」的方式來擴展JMeter對新協議的測試,仍是有必定的工做量,特別是若是界面功能比較豐富的話,實現界面的那個類會比較複雜。若是對界面的要求不是很高,那麼還有一種比較簡單的可選項是經過擴展AbstractJavaSamplerClient,經過擴展該類,能夠實現對簡單的測試配置屬性進行設置,並在runTest方法的實現中對目標系統發出請求
public SampleResult runTest(JavaSamplerContext context)
該方法的返回值是SampleResult,就是驗證測試結果,與上文中實現步驟3比較相似。讀者能夠參見本文的參考資料中關於AbstractJavaSamplerClient中列出的幾篇文章。
若是用戶自定義的協議的測試,單臺機器可以模擬的客戶端是有限的,若是針對大規模的協議測試(好比本文舉例的Kafka),可能須要準備大量的測試機器對被測系統進行打壓,這個過程須要大量的準備機器環境,以及管理這些環境的工做,致使工做效率比較低、並且容易出錯。XMeter將這些過程遷移至雲端,彈性伸縮管理這些壓力機,用戶只要關注測試腳本的實現過程,而無需關心這些測試環境的管理,從而大大下降了大規模性能測試的複雜度。另外XMeter提供了豐富的測試報告,讓性能問題一目瞭然。
JMeter擴展官方文檔
AbstractJavaSamplerClient的方式擴展JMeter文章1
AbstractJavaSamplerClient的方式擴展JMeter文章2
AbstractJavaSamplerClient的方式擴展JMeter文章3
XMeter成立於2016年,核心團隊都來自於IBM,是一家領先技術的性能測試持續集成諮詢與服務提供商。咱們致力於提供給客戶可靠,簡單,低成本的性能測試解決方案。