基于jmeter-dubbo协议压测实践

摘要:
为了解决公司RPCdubbo协议调用的压力测试问题,需要升级jmeter压力测试组件,并扩展压力测试协议支持。Dubbo泛化调用原理在执行Dubbo协议接口的压力测试之前,需要提前了解Dubbo通用调用的过程和原理。Jmeter压力测试组件的实践、使用、安装和准备https://github.com/thubbo/jmeter-plugins-for-apache-dubbo/releases/tag/2.7.8下载dubbo插件jmeter插件dubbo 2.7.8-jar-with-dependencies。jar来放置jmeterlibext目录,或下载并使用jmeter插件dubbo jar,但此方法需要引入以下依赖的jar包。参数值、基本包装类和基本子类型直接使用值,例如int为1,boolean为true,用户定义类和List或Map使用json格式数据。

背景

为了满足公司业务发展及性能要求,公司技术架构在很多业务接口调用设计中引用到了dubbo协议调用方式,对于以前HTTP feign调用的接口转为dubbo泛化调用后,接口性能如何?有何影响?需要进行压测评估。为解决公司RPC dubbo协议调用压测问题,需升级jmeter压测组件,扩展压测协议支持。

 

Dubbo泛化调用原理

在进行dubbo协议接口压测实施之前,我们有必要事先了解dubbo泛化调用的过程和原理。

 

所谓dubbo泛化调用即通常我们想调用别人的dubbo服务时,我们需要在项目中引入对应的jar包。而泛化调用的作用是,我们无需依赖相关jar包,也能调用到该服务。

dubbo泛化调用,主要涉及API方式和Spring方式,下面就是2种dubbo调用的简单代码示例:

packagecom.dewu.main.dubbo.provider.service.impl;

public interfacedubboHalloService {

StringsayHallo(String name);

}

API调用方式

ReferenceConfig<GenericService>referenceConfig=newReferenceConfig<>();

referenceConfig.setApplication(newApplicationConfig("test"));

referenceConfig.setRegistry(newRegistryConfig("8848"));

referenceConfig.setInterface("com.dewu.main.dubbo.provider.service.impl.dubboHalloService");

referenceConfig.setGeneric(true);

GenericServicegenericService=referenceConfig.get();

 

Objectresult=genericService.$invoke(

"hallo",

newString[]{"java.lang.String"},

newObject[]{"1234"});

 

System.out.println(result);

Spring调用方式

xml配置设置

<dubbo:reference id="dubboHalloService"interface="com.dewu.main.dubbo.provider.service.impl.dubboHalloService"generic="true"/>

注入使用

@Service

publicclassPersonService{

 

@Resource(name="halloService")

privateGenericServicegenericService;

 

publicvoidsayHallo(){

Objectresult=genericService.$invoke(

"hallo",

newString[]{"java.lang.String"},

newObject[]{"1234"});

System.out.println(result);

}

}

在两种调用方式中,我们都需要使用被调用接口的字符串参数生成GenericService,通过GenericService的$invoke间接调用目标接口的接口。

public interface GenericService{

Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;

}

 

泛化调用和直接调用在消费者者端,在使用上的区别是,我们调用服务时使用的接口为GenericService,方法为$invoker。在底层的区别是,消费者端发出的rpc报文发生了变化。

在使用上,不管哪种配置方式,我们都需要配置generic=true,设置generic=true后,RefereceConfig的interfaceClass会被强制设置为GenericService。

 

Jmeter压测组件实践使用

安装准备

https://github.com/thubbo/jmeter-plugins-for-apache-dubbo/releases/tag/2.7.8下载dubbo插件jmeter-plugins-dubbo-2.7.8-jar-with-dependencies.jar放置jmeter libext目录,或者下载使用jmeter-plugins-dubbo.jar,但此种方式需要引入如下相关依赖JAR包。

 

dubbo-2.5.3.jar

javassist-3.15.0-GA.jar

zookeeper-3.4.6.jar

zkclient-0.1.jar

jline-0.9.94.jar

netty-3.7.0-Final.jar

slf4j-api-1.7.5.jar

log4j-over-slf4j-1.7.5.jar

 

注意:此两种方式不能同时使用,否则会产生JAR包冲突

 

使用步骤

1.创建线程组->添加Dubbo Sample请求

 基于jmeter-dubbo协议压测实践第1张

2.配置注册中心地址,填写压测请求接口和方法以及请求体参数

基于jmeter-dubbo协议压测实践第2张

3.点击运行,查看响应结果

基于jmeter-dubbo协议压测实践第3张

组件详解

注册中心类型

基于jmeter-dubbo协议压测实践第4张

  • Protocol=none为直连方式
  • Protocol=zookeeper使用zk注册中心
  • Protocol=使用nacas注册中心
  • Protocol=multicast为广播方式
  • Protocol=redis使用redis注册中心
  • Protocol=simple使用simple注册中心

 

请求参数描述

  1. 当使用zk,address填入zk地址(集群地址使用","分隔),使用dubbo直连,address填写直连地址和服务端口。
  2. timeout:服务方法调用超时时间(毫秒)。
  1. version:服务版本,与服务提供者的版本一致。
  2. retries:远程服务调用重试次数,不包括第一次调用,不需要重试请设为0。
  1. cluster:集群方式,可选方式类型:failover/failfast/failsafe/failback/forking。
  2. group: 服务分组,当一个接口有多个实现,可以用分组区分,必需和服务提供方一致。
  1. interface需要填写接口类型完整名称,含包名。
  2. 参数支持任何类型,包装类直接使用java.lang下的包装类,小类型使用:int、float、shot、double、long、byte、boolean、char,自定义类使用类完全名称。
  1. 参数值,基础包装类和基础小类型直接使用值,例如:int为1,boolean为true等,自定义类与List或者Map等使用json格式数据。

 

参数类型示例

基于jmeter-dubbo协议压测实践第5张

Java类型

paramType

paramValue

int

int

1

int[]

int[]

[1, 2]

double

double

1.2

double[]

double[]

[1.2, 1.3]

short

short

1

short[]

short[]

[1, 2]

float

float

1.2

float[]

float[]

[1.2, 1.3]

long

long

1

long[]

long[]

[1, 2]

byte

byte

字节

byte[]

byte[]

字节

boolean

boolean

true

false

boolean[]

boolean[]

[true, false]

char

char

A,如果字符过长取值为:"STR".charAt(0)

char[]

char[]

[A, B]

java.lang.String

java.lang.String

String

string

"foo"

foo

java.lang.String[]

java.lang.String[]

String[]

string[]

["foo1", "foo2"]

java.lang.Integer

java.lang.Integer

Integer

integer

1

java.lang.Integer[]

java.lang.Integer[]

Integer[]

integer[]

[1, 2]

java.lang.Double

java.lang.Double

Double

1.2

java.lang.Double[]

java.lang.Double[]

Double[]

[1.2, 1.3]

java.lang.Short

java.lang.Short

Short

1

java.lang.Short[]

java.lang.Short[]

Short[]

[1, 2]

java.lang.Long

java.lang.Long

Long

1

java.lang.Long[]

java.lang.Long[]

Long[]

[1, 2]

java.lang.Float

java.lang.Float

Float

1.2

java.lang.Float[]

java.lang.Float[]

Float[]

[1.2, 1.3]

java.lang.Byte

java.lang.Byte

Byte

字节

java.lang.Byte[]

java.lang.Byte[]

Byte[]

字节

java.lang.Boolean

java.lang.Boolean

Boolean

true

false

java.lang.Boolean[]

java.lang.Boolean[]

Boolean[]

[true, false]

JavaBean

com.your.package.BeanName

{"att1":"foo","att2":"foo2"}

JavaBean[]

com.your.package.BeanName

[{"att1":"foo"}, {"att1":"foo2"}]

java.util.Map以及子类

java.util.Map以及子类

{"att1":"foo","att2":"foo2"}

java.util.Map<String,JavaBean>

java.util.Map

{"keyName":{"att1":"foo"}}

java.util.HashMap<Object,Object>

java.util.HashMap

{"keyName":{"att1":"foo"}}

java.util.Collection以及子类

java.util.Collection以及子类

["a","b"]

java.util.List<String>

java.util.List

["a", "b"]

java.util.List<JavaBean>

java.util.List

[{"att1":"foo1"}, {"att1":"foo2"}]

java.util.List<Map<Object, JavaBean>>

java.util.List

[{"keyName1":{"att1":"foo1"}}, {"keyName2":{"att1":"foo1"}}]

java.util.List<Long>

java.util.List

[1, 2, 3]

java.util.ArrayList<Object>

java.util.ArrayList

["foo" , 1, true]

 

踩坑指南

1.jar包冲突

2.缺少protostuff jar包依赖

3.参数格式问题导致调用报错

4.provide服务提供者注册出现问题导致连接拒绝

参考文档

https://github.com/thubbo/jmeter-plugins-for-apache-dubbo

免责声明:文章转载自《基于jmeter-dubbo协议压测实践》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux下keepalived配置关于c++正则表达式的用法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

xml中“ &amp;lt; &amp;gt; ”转义为“ &amp;amp;lt; &amp;amp;gt; ”问题处理

曾经也碰到过类似问题,解决方法是在发送或者解析报文前执行上面的方法将内容转义一下,现在我用dom4j组装如下的报文(报文体中内容传输时加密处理),大致介绍一下上面方法的使用,具体看代码。 importjava.io.StringReader; importjava.io.StringWriter; importjava.math.BigDecima...

Perl模式匹配

       Perl 内置的模式匹配让你能够简便高效地搜索大量的数据。不管你是在一个巨型的商业门户站点上用于扫描每日感兴趣的珍闻报道,还是在一个政府组织里用于精确地描述人口统计(或者人类基因组图),或是在一个教育组织里用于在你的 web 站点上生成一些动态信息,Perl 都是你可选的工具。这里的一部分原因是 Perl 的数据库联接能力,但是更重要的原因是...

多平台Client TCP通讯组件

Beetle.NetPackage是一个多平台Client Socket TCP通讯组件(Apache License 2.0),组件制统一的对象协议制定规则,可以灵活方便地通过对象来描述TCP通讯交互。现有支持平台有Flash,.NET和Android。组件为了统一编写规范制定了不同语言平台下访问TCP服务的统一处理规则;分别有协议描述规范和消息处理控...

java生成解析xml的另外两种方法JAXB

   JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示...

MyBatis映射文件(编写SQL语句;可有可无(无的时候,使用注解编程))

 一、映射文件  1.简单的增删改(需要commit)---查 MyBatis允许增删改直接定义以下类型返回值   Integer、Long、Boolean、void 我们需要手动提交数据。   sqlSessionFactory.openSession();===>需要手动提交   sqlSessionFactory.openSession(tr...

在lua的string库和正则表达式

一.前提要了解一下lua 的string几个方法 1. string库中所有的字符索引从前往后是1,2,...;从后往前是-1,-2,... 2. string库中所有的function都不会直接操作字符串,而是返回一个结果 string.len(s):返回字符串的长度. string.lower(s):变小写. string.upper(s):变大写....