JMeter擴(kuò)展插件實(shí)現(xiàn)對(duì)自定義協(xié)議進(jìn)行支持

摘要##

JMeter本身提供了插件機(jī)制,允許第三方擴(kuò)展JMeter以支持JMeter不支持的協(xié)議的測(cè)試。本文以擴(kuò)展一個(gè)簡單的Apache Kafka producer sampler為例描述了如何對(duì)JMeter進(jìn)行擴(kuò)展,方便地實(shí)現(xiàn)對(duì)新協(xié)議的支持。

Kafka簡介##

Apache Kafka是由Apache軟件基金會(huì)開發(fā)的一個(gè)開源消息系統(tǒng)項(xiàng)目。Kafka最初是由LinkedIn開發(fā),并于2011年初開源。2012年10月從Apache孵化器畢業(yè)。該項(xiàng)目的目標(biāo)是為處理實(shí)時(shí)數(shù)據(jù)提供一個(gè)統(tǒng)一、高通量、低等待的平臺(tái)。

如下圖所示,Kafka的producer(數(shù)據(jù)生產(chǎn)者)通過Socket向Kafka集群上配置好的主題(topic)發(fā)送數(shù)據(jù),consumer(數(shù)據(jù)消費(fèi)者)在另外一端消費(fèi)由生產(chǎn)者那邊產(chǎn)生的數(shù)據(jù),并進(jìn)行業(yè)務(wù)的處理。Kafka作為一個(gè)優(yōu)秀的消息處理系統(tǒng),在集群配置,主題管理等方面有很多需要深入理解和優(yōu)化等地方,本文的重點(diǎn)是JMeter的擴(kuò)展,以Kafka的生產(chǎn)者為例來描述如何利用JMeter來模擬大量的生產(chǎn)者的調(diào)用,更多關(guān)于Kafka的細(xì)節(jié)請(qǐng)參考它的官方文檔

Kafka生產(chǎn)、消費(fèi)者模型

準(zhǔn)備工作##

擴(kuò)展實(shí)現(xiàn)JMeter插件之前,需要先考慮清楚哪些選項(xiàng)需要暴露給測(cè)試人員。就像HTTP測(cè)試中,需要讓用戶輸入服務(wù)器地址,端口號(hào),路徑等,同線程組里的連接是否共用等,如果提供是否共用連接這種選項(xiàng)的話,也需要在界面中體現(xiàn),當(dāng)然實(shí)現(xiàn)插件的時(shí)候處理連接的代碼也會(huì)有所不同。

往Kafka上發(fā)送消息的時(shí)候,需要提供一些基本配置信息(實(shí)際Kafka的生產(chǎn)者配置不止這些),如果讀者對(duì)下面所說的內(nèi)容不了解也不要緊,只需要理解準(zhǔn)備這些的目的是為了將這些配置信息提供給Kafka測(cè)試人員,在開始測(cè)試之前可以針對(duì)被測(cè)系統(tǒng)進(jìn)行配置。

服務(wù)器所在地址,在Kafka中稱之為Brokers

發(fā)送的主題的名字

Message Serializer,消息通過網(wǎng)絡(luò)發(fā)送,需要將其序列化,這里指定的是消息序列化的方式

Key Serializer,Kafka發(fā)送消息的時(shí)候,可以指定Key,Key Serializer的主要作用是指定Key的序列化方式

發(fā)送的消息

下圖是本文最終完成的JMeter Kafka插件的截圖,測(cè)試開始之前需要輸入上文所列的信息。

Kafka JMeter插件截圖

JMeter插件實(shí)現(xiàn)步驟1 - 準(zhǔn)備開發(fā)環(huán)境##

JMeter插件實(shí)現(xiàn)是標(biāo)準(zhǔn)的Java代碼,打開Eclipse(作者使用的是4.5.2),新建一個(gè)Maven項(xiàng)目。我們的項(xiàng)目中需要引用到JMeter本身提供的一些庫,包括ApacheJMeter_core和ApacheJmeter_java,并且對(duì)JMeter的版本依賴是3.0。另外,還需要對(duì)Kafka的類庫也需要引入,pom.xml中依賴部分的代碼如下。

UTF-83.0org.apache.jmeterApacheJMeter_core${jmeter-version}providedorg.apache.jmeterApacheJMeter_java${jmeter-version}providedorg.apache.kafkakafka_2.9.20.8.1.1org.apache.zookeeperzookeeper

工程創(chuàng)建完畢之后,開始編寫代碼來實(shí)現(xiàn)插件。

JMeter插件實(shí)現(xiàn)步驟2 - 自定義界面##

JMeter的插件機(jī)制會(huì)在$JMETER_HOME/lib/ext目錄下去動(dòng)態(tài)加載符合指定條件的JAR包,并在JMeter中顯示出來。比如要擴(kuò)展UI的話,擴(kuò)展的Java類的包名必須是”.gui.”,同樣的擴(kuò)展函數(shù)的Java類的包名必須是”.function.”.

新建一個(gè)類,org.apache.jmeter.protocol.kafka.control.gui.KafkaSamplerUI,并指定其父類為AbstractSamplerGui。該類需要實(shí)現(xiàn)以下的功能:

1)界面布局與控件。JMeter的界面是標(biāo)準(zhǔn)的Swing,所以里面的控件和布局都是標(biāo)準(zhǔn)的Swing寫法。

2)界面與Sampler之間的數(shù)據(jù)交換。Sampler在JMeter中繼承的是TestElement,用戶輸入的數(shù)據(jù)都是保存在Sampler中的,因此可以認(rèn)為這個(gè)是界面的模型。界面與模型(Sampler)之間的數(shù)據(jù)交換需要實(shí)現(xiàn)父類的下面幾個(gè)方法,

publicvoidconfigure(TestElement el)

該方法用于把Sampler中的數(shù)據(jù)加載到界面中。在實(shí)現(xiàn)自己的邏輯之前,先調(diào)用一下父類的方法super.configure(el),這樣可以確??蚣茏詣?dòng)為你加載一些缺省數(shù)據(jù),比如Sampler的名字。

publicvoidmodifyTestElement(TestElement e)

這個(gè)方法用于把界面的數(shù)據(jù)移到Sampler中,剛好與上面的方法相反。在調(diào)用自己的實(shí)現(xiàn)方法之前,請(qǐng)先調(diào)用一下super.configureTestElement(e),這個(gè)會(huì)幫助移到一些缺省的數(shù)據(jù)。

publicTestElementcreateTestElement()

該方法創(chuàng)建一個(gè)新的Sampler,然后將界面中的數(shù)據(jù)設(shè)置到這個(gè)新的Sampler實(shí)例中。

publicvoidclearGui()

該方法會(huì)在reset新界面的時(shí)候調(diào)用,這里可以填入界面控件中需要顯示的一些缺省的值。

在本文的實(shí)現(xiàn)中,分別實(shí)現(xiàn)上面的那些方法,包括顯示5個(gè)控件(4個(gè)控制參數(shù)的控件在一個(gè)panel里,發(fā)送的消息的控件在另外一個(gè)panel里),以及另外的幾個(gè)方法用于和Sampler之間的數(shù)據(jù)交換等。完整的代碼請(qǐng)參見這里

JMeter插件實(shí)現(xiàn)步驟3 - 自定義Kafka Sampler##

新建一個(gè)Sampler,org.apache.jmeter.protocol.kafka.sampler.KafkaSampler,并指定其父類為AbstractSampler。該類需要實(shí)現(xiàn)以下的功能:

1)增加一些getter/setter方法,這些方法用于與UI之間的數(shù)據(jù)交換,這些數(shù)據(jù)在用戶保存/打開腳本的時(shí)候?qū)⒈蛔詣?dòng)序列化/反序列化。

2)實(shí)現(xiàn)sample方法:

publicSampleResultsample(Entry entry)

該方法是JMeter實(shí)現(xiàn)對(duì)目標(biāo)系統(tǒng)發(fā)起請(qǐng)求實(shí)際工作的地方。主要的工作是記錄請(qǐng)求處理時(shí)間,對(duì)返回結(jié)果進(jìn)行處理和判斷,并根據(jù)處理結(jié)果返回SampleResult,該SampleResult中需要指定返回的內(nèi)容是否成功,以及消息等。該方法的基本實(shí)現(xiàn)框架如下所示:

publicSampleResultsample(Entry entry){? ? ? ? SampleResult result =newSampleResult();? ? ? ? result.setSampleLabel(getName());try{? ? ? ? ? ? result.sampleStart();//對(duì)目標(biāo)系統(tǒng)發(fā)出測(cè)試請(qǐng)求result.sampleEnd();? ? ? ? ? ? result.setSuccessful(true);? ? ? ? ? ? result.setResponseCodeOK();? ? ? ? }catch(Exception e) {? ? ? ? ? ? result.sampleEnd();// stop stopwatchresult.setSuccessful(false);? ? ? ? ? ? result.setResponseMessage("Exception: "+ e);// get stack trace as a String to return as document datajava.io.StringWriter stringWriter =newjava.io.StringWriter();? ? ? ? ? ? e.printStackTrace(newjava.io.PrintWriter(stringWriter));? ? ? ? ? ? result.setResponseData(stringWriter.toString(),null);? ? ? ? ? ? result.setDataType(org.apache.jmeter.samplers.SampleResult.TEXT);? ? ? ? ? ? result.setResponseCode("FAILED");? ? ? ? }returnresult;? ? }

本文的實(shí)現(xiàn)中,生成一個(gè)Kafka的Producer對(duì)象,并將用戶界面里指定的信息發(fā)送到Kafka服務(wù)器上。完整的代碼請(qǐng)參見這里。

JMeter插件實(shí)現(xiàn)步驟4 - 打包、部署##

打包過程與普通的Maven項(xiàng)目相似,但是需要注意的是本插件需要把Kafka相關(guān)的依賴庫文件也一并打入,否則還需要單獨(dú)準(zhǔn)備所依賴的JAR包。因此在pom.xml中加入下面的build插件。右擊工程 》Run As 》Maven install,運(yùn)行成功后,在工程的target目錄下會(huì)生成一個(gè)kafka_jmeter-jar-with-dependencies.jar,這個(gè)就是我們打好的插件。

${project.artifactId}installorg.apache.maven.pluginsmaven-compiler-plugin2.5.11.71.7org.apache.maven.pluginsmaven-assembly-pluginjar-with-dependenciesassemble-allpackagesingle

插件開發(fā)完成后,將kafka_jmeter-jar-with-dependencies.jar拷貝到$JMETER_HOME/lib/ext目錄下,如果之前已經(jīng)打開了JMeter,則需要將JMeter關(guān)閉重啟。

JMeter插件實(shí)現(xiàn)步驟5 - 測(cè)試插件##

新建一個(gè)測(cè)試腳本,加入一個(gè)線程組,然后添加一個(gè)Sampler,如果運(yùn)行正常,在子菜單中應(yīng)該能看到我們擴(kuò)展出來的“Kafka Sampler”。

開發(fā)好的插件

修改一下線程組里的線程數(shù),則能實(shí)現(xiàn)多虛擬用戶的并發(fā)測(cè)試了。下圖是“查看結(jié)果樹”里面顯示的內(nèi)容。

查看結(jié)果樹中的內(nèi)容

下圖是Kafka的消費(fèi)者端,能看到相關(guān)的消息已經(jīng)發(fā)送成功。

服務(wù)器端控制臺(tái)輸出

更多擴(kuò)展方式##

如本文所示,如果通過比較“標(biāo)準(zhǔn)”的方式來擴(kuò)展JMeter對(duì)新協(xié)議的測(cè)試,還是有一定的工作量,特別是如果界面功能比較豐富的話,實(shí)現(xiàn)界面的那個(gè)類會(huì)比較復(fù)雜。如果對(duì)界面的要求不是很高,那么還有一種比較簡單的可選項(xiàng)是通過擴(kuò)展AbstractJavaSamplerClient,通過擴(kuò)展該類,可以實(shí)現(xiàn)對(duì)簡單的測(cè)試配置屬性進(jìn)行設(shè)置,并在runTest方法的實(shí)現(xiàn)中對(duì)目標(biāo)系統(tǒng)發(fā)出請(qǐng)求

publicSampleResultrunTest(JavaSamplerContext context)

該方法的返回值是SampleResult,就是驗(yàn)證測(cè)試結(jié)果,與上文中實(shí)現(xiàn)步驟3比較類似。讀者可以參見本文的參考資料中關(guān)于AbstractJavaSamplerClient中列出的幾篇文章。

大規(guī)模自定義協(xié)議測(cè)試 - XMeter幫您提高效率,降低成本##

如果用戶自定義的協(xié)議的測(cè)試,單臺(tái)機(jī)器能夠模擬的客戶端是有限的,如果針對(duì)大規(guī)模的協(xié)議測(cè)試(比如本文舉例的Kafka),可能需要準(zhǔn)備大量的測(cè)試機(jī)器對(duì)被測(cè)系統(tǒng)進(jìn)行打壓,這個(gè)過程需要大量的準(zhǔn)備機(jī)器環(huán)境,以及管理這些環(huán)境的工作,導(dǎo)致工作效率比較低、而且容易出錯(cuò)。XMeter將這些過程遷移至云端,彈性伸縮管理這些壓力機(jī),用戶只要關(guān)注測(cè)試腳本的實(shí)現(xiàn)過程,而無需關(guān)心這些測(cè)試環(huán)境的管理,從而大大降低了大規(guī)模性能測(cè)試的復(fù)雜度。另外XMeter提供了豐富的測(cè)試報(bào)告,讓性能問題一目了然。

參考資料##

JMeter擴(kuò)展官方文檔

AbstractJavaSamplerClient的方式擴(kuò)展JMeter文章1

AbstractJavaSamplerClient的方式擴(kuò)展JMeter文章2

AbstractJavaSamplerClient的方式擴(kuò)展JMeter文章3

關(guān)于我們##

XMeter成立于2016年,核心團(tuán)隊(duì)都來自于IBM,是一家領(lǐng)先技術(shù)的性能測(cè)試持續(xù)集成咨詢與服務(wù)提供商。我們致力于提供給客戶可靠,簡單,低成本的性能測(cè)試解決方案。

作者:XMeter性能測(cè)試云服務(wù)

鏈接:http://www.itdecent.cn/p/08fe9b6c3f84

來源:簡書

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容