zoukankan      html  css  js  c++  java
  • 基于jmeter-dubbo协议压测实践

    背景

    为了满足公司业务发展及性能要求,公司技术架构在很多业务接口调用设计中引用到了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请求

     

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

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

    组件详解

    注册中心类型

    • 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格式数据。

     

    参数类型示例

    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

  • 相关阅读:
    Fancybox丰富的弹出层效果
    oracle wm_concat(column)函数的使用
    asp.net下ajax.ajaxMethod使用方法
    sql2008 附加数据库出错解决方法
    关于mysql-5.7.13-winx64服务无法启动的解决方法
    解决懒加载异常
    学生各科成绩,平均分,总分的展示
    docker desktop v20 设置文件路径,windows docker 设置设置路径
    自动化运维工具:jumpserver/jms_all
    linux kill 进程正则表达式
  • 原文地址:https://www.cnblogs.com/johnny-chen/p/14897366.html
Copyright © 2011-2022 走看看