invoke 测试dubbo接口(dubbo测试接口调用)

网友投稿 542 2023-04-15


本篇文章给大家谈谈invoke 测试dubbo接口,以及dubbo测试接口调用对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。 今天给各位分享invoke 测试dubbo接口的知识,其中也会对dubbo测试接口调用进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

关于jmeter测试dubbo接口方式

本文章介绍如何使用jmeter测试dubbo接口,涉及如下两种方式

1.使用官方dubbo版本包测试dubbo接口

2.通过自己编写java请求插件,实现dubbo调用

选择方式1或方式2并没有什么区别,取决于部分自研公司对dubbo进行了封装,导致官方提供的dubbo包并不适用于方式1,则可以通过方式2去调用

https://github.com/ningyu1/jmeter-plugins-dubbo/releases
解压tar将获取到的jar包放入${JMETER_HOME}\lib\ext路径下(这里获取到的jar包为jmeter-plugins-dubbo-2.7.1-jar-with-dependencies),重启jmeter应用(这里重启完应用会添加取样器会多出一个dubbo sample)

右键添加,选择线程-线程组

2.光标对准线程组右键添加-取样器-dubbo sample

此处需要关注,当方法接收的是一个String,或者List等类型的参数,可参照截图配置
那么当方法接收的参数是一个对象时,需要获取对接接口的api jar包并关联到当前测试计划
选中测试计划,点击下方浏览按钮,选择对应的jar包

传参的具体方式可参照如下

接口1返回:

接口2返回

看了下网上的大多请求都是单接口请求dubbo,这样就会导致,每次有新的接口的时候都得去更新新的请求,这里提供一个一劳永逸的方法,通过泛化调用,实现一个jar请求可适配所有接口,一般看到这个文章的可能大多都是测试的同学,对于当前方法需要对java有一定的基础,所以这个时候就体验到学习的重要性了,下面开始操作吧

file-new-project,选择maven

输入组织-坐标后点击next

按需配置名称路径后点击finsh

pom.xml配置如下

实现方式如下

打包操作

左侧窗口为生成的jar包和lib目录

这里要说明下,网上提供了一种方式,通过修改安装目录bin下jmeter.properties文件关联lib下的依赖
文件中增加如下(通过尝试,这么做会导致jmeter启动由于jar包加载顺序的问题,ui部分控件不可用)

这里我使用的是另一种更为简便的方式
将原安装目录lib下ext修改为extbak
新建ext,并将工程lib下的jar包和dobbo-jmeter-interface-1.0-SNAPSHOT.jar放入之
由于可能会用到随机函数,从extbak获取ApacheJMeter_functions.jar,也放入到新建的ext目录下
重启jmeter,稍等片刻

添加java请求

添加结果树

点击运行后,结果树信息如下

后续可自行配置断言和随机参数等

telnet调用Dubbo接口的坑

通过telnet命令,去调⽤使用了dubbo框架的查询订单接口,一直调用出错, 查询后台⽇志,发现uAccount字段没有传递过去,为null。

通过telnet命令调用的dubbo接口,会在InvokeTelnetHandler将json字符串转换为对应的请求参数对象,在95行中,通过PojoUtils.realize()方法进行转换。

在PojoUtils中,主要是通过realize0这个方法进行反序列化,在438和439来获取属性的set方法或者直接获取这个属性,然后在下面调用反射调用set方法或者直接通过反射赋值。

获取set方法的时候,把set紧跟的这个字符转换成了大写,也就是setUAccount,咱们通过idea自动生成get/set方法,像这种类型(小写开头,紧跟大写字母)产生的get/set后面紧跟的第一个字母都是小写字母,所以就获取不到set方法了。

getField方法中,由于咱们设置的属性一般都private属性的,所有这里通过class.getField()和class.getFields()都获取不到。

通过dubbo接口调用时,会通过序列化组件将请求对象通过指定的协议(默认hessian2)转换为二进制,此方式转化时不会出现以上问题。

Dubbo配置参数详解-generic

画外音:目前Dubbo在开源中国举办的2019年度最受欢迎中国开源软件中排名第3名,支持Dubbo的朋友可以去投票哇。 2019年度最受欢迎中国开源软件

Consumer端正常调用Dubbo服务时,一般都需要服务提供方提供一个jar包,只有在项目中引入该jar包,才能调用相关服务;能不能向http调用那样,我只需要知道我要调用的url就可以直接调用Dubbo服务?

有的,这就是generic做的事。

generic :通用服务调用,当我们已经知道我们要调用的服务的全限定名及方法,就不需要服务提供者的jar就能调用Dubbo服务了。

generic要配合interfaceName参数一起使用,其中interfaceName是Dubbo服务的全限定名,比如:

当provider接收到请求时,会调用一系列的过滤器对请求进行处理,这其中就包含处理generic的过滤器: GenericFilter
该过滤器会判断调用的方法是否是$invoke,如果是则会通过反射调用正在的方法

笔者认为该参数最大的用武之地是作为网关使用,笔者所在公司的网关就提供了http转换成dubbo接口调用的功能,前端使用http调用,后端使用dubbo服务进行处理;网关提供一个接口配置页面,只需要业务方在页面配置url与dubbo接口的转换关系即可,网关不需要引用服务提供者的jar包,如果接口有变动,网关无需知道,只要业务方修改配置即可。

dubbo泛化调用使用及原理解析

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

这个特性一般使用在网关类项目中,在业务开发中基本不会使用。

假设我现在要调用下面的接口服务

在xml文件做以下配置

然后注入使用

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

$invoke的三个参数分别为,方法名,方法参数类型数组,方法参数数组。

可以看到泛化调用的一个复杂性在于$invoke的第三个参数的组装,下面介绍几种复杂入参的调用方式

首先丰富提供者接口

与入参相似,虽然$invoke的返回定义为Object,实际上针对不同类型有不同的返回。

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

在使用上,不管哪种配置方式,我们都需要配置generic=true

设置generic=true后,RefereceConfig的interfaceClass会被强制设置为GenericService

这也使得我们的RefereanceBean返回的是GenericService类型的代理。

生成的代理是GenericService的代理只是我们使用方式上的变化,更为核心的是,底层发送的rpc报文发生了什么变化。

Dubbo的rpc报文分为header和body两部分。我们这边只需要关注body部分。构造逻辑如下

那么我们通过直接调用与泛化调用ByeService的bye方法在报文上有啥区别呢?

我一开始以为报文中的path是GenericeService,其实并没有,path就是我们调用的目标方法。

path来源???todo

而报文中的方法名,方法参数类型以及具体参数,还是按照GenericeService的$invoke方法入参传递的。

这么个二合一的报文,发送到提供者那边,它估计也会很懵逼,我应该怎么执行?

所以针对泛化调用报文还会把generic=true放在attchment中传递过去

具体逻辑在GenericImplFilter中。

GenericImplFilter中有很多其他逻辑,比如泛化调用使用的序列化协议,正常接口走泛化调用的模式,我们只需要设置attachment的那部分。

知道消费者端报文发生了什么变化,那么接下来就去看提供者端如何处理这个改造后的报文。

总结一下ReferenceConfig中interfaceClass和interfaceName的区别?(这道面试题好像不错)

interfaceClass用于指定生成代理的接口
interfaceName用于指定发送rpc报文中的path(告诉服务端我要调用那个服务)

消费者泛化调用的rpc报文传递到提供者还不能直接使用,虽然path是对的,但是实际的方法名,参数类型,参数要从rpc报文的参数中提取出来。

GenericFilter就是用来做这件事情。

在提供者这边,针对泛化调用的逻辑全部封装到了GenericFilter,解耦的非常好。

注意第4个条件,一开始很疑惑,后来发现rpc报文中的path是目标接口的,这边invoker.getInterface()返回的肯定就是实际接口了

这边有个疑问,为什么这边还要再次反序列化一次,netty不是有decoder么??

嗯,你别忘了,针对一个POJO你传过来是一个Map,从Map转换为POJO需要这边进一步处理。

这边需要注意一下!!针对接口的泛化调用,抛出的异常都会经过GenericException包装一下。

从功能上来看,泛化调用提供了在没有接口依赖情况下进行的解决方案,丰富框架的使用场景。
从设计上来看,泛化调用的功能还是通过扩展的方式实现的,侵入性不强,值得学习借鉴。

Dubbo——Mock 机制

Mock 机制是 RPC 框架中非常常见、也非常有用的功能,不仅可以用来实现服务降级,还可以用来在测试中模拟调用的各种异常情况。Dubbo 中的 Mock 机制是在 Consumer 这一端实现的,具体来说就是在 Cluster 这一层实现的。

在前面深入介绍了 Dubbo 提供的多种 Cluster 实现以及相关的 Cluster Invoker 实现,其中的 ZoneAwareClusterInvoker 就涉及了 MockClusterInvoker 的相关内容。本文我们就来介绍 Dubbo 中 Mock 机制的全链路流程,不仅包括与 Cluster 接口相关的 MockClusterWrapper 和 MockClusterInvoker,还会回顾之前的 Router 和 Protocol 接口,分析它们与 Mock 机制相关的实现。

Cluster 接口有两条继承线(如下图所示):一条线是 AbstractCluster 抽象类,这条继承线涉及的全部 Cluster 实现类;另一条线是 MockClusterWrapper 这条线。

MockClusterWrapper 是 Cluster 对象的包装类,在之前介绍 Dubbo SPI 机制时已经分析过 Wrapper 的功能,MockClusterWrapper 类会对 Cluster 进行包装。下面是 MockClusterWrapper 的具体实现,其中会在 Cluster Invoker 对象的基础上使用 MockClusterInvoker 进行包装:

MockClusterInvoker 是 Dubbo Mock 机制的核心,它主要是通过 invoke()、doMockInvoke() 和 selectMockInvoker() 这三个核心方法来实现 Mock 机制的。

下面就来逐个介绍这三个方法的具体实现。

首先来看 MockClusterInvoker 的 invoke() 方法,它会先判断是否需要开启 Mock 机制。如果在 mock 参数中配置的是 force 模式,则会直接调用 doMockInvoke() 方法进行 mock。如果在 mock 参数中配置的是 fail 模式,则会正常调用 Invoker 发起请求,在请求失败的时候,会调动 doMockInvoke() 方法进行 mock。下面是 MockClusterInvoker 的 invoke() 方法的具体实现:

在 doMockInvoke() 方法中,首先调用 selectMockInvoker() 方法获取 MockInvoker 对象,并调用其 invoke() 方法进行 mock 操作。doMockInvoke() 方法的具体实现如下:

selectMockInvoker() 方法中并没有进行 MockInvoker 的选择或是创建,它仅仅是将 Invocation 附属信息中的 invocation.need.mock 属性设置为 true,然后交给 Directory 中的 Router 集合进行处理。selectMockInvoker() 方法的具体实现如下:

MockInvokersSelector 是 Dubbo Mock 机制相关的 Router 实现,在未开启 Mock 机制的时候,会返回正常的 Invoker 对象集合;在开启 Mock 机制之后,会返回 MockInvoker 对象集合。MockInvokersSelector 的具体实现如下:

在 getMockedInvokers() 方法中,会根据 URL 的 Protocol 进行过滤,只返回 Protocol 为 mock 的 Invoker 对象,而 getNormalInvokers() 方法只会返回 Protocol 不为 mock 的 Invoker 对象。

介绍完 Mock 功能在 Cluster 层的相关实现之后,还要来看一下 Dubbo 在 RPC 层对 Mock 机制的支持,这里涉及 MockProtocol 和 MockInvoker 两个类。

首先来看 MockProtocol,它是 Protocol 接口的扩展实现,扩展名称为 mock。MockProtocol 只能通过 refer() 方法创建 MockInvoker,不能通过 export() 方法暴露服务,具体实现如下:

下面再来看 MockInvoker 是如何解析各类 mock 配置的,以及如何根据不同 mock 配置进行不同处理的。这里重点来看 MockInvoker.invoke() 方法,其中针对 mock 参数进行的分类处理具体有下面三条分支:

MockInvoker.invoke() 方法的具体实现如下所示:

针对 return 和 throw 的处理逻辑比较简单,但 getInvoker() 方法略微复杂些,其中会处理 MOCK_MAP 缓存的读写、Mock 实现类的查找、生成和调用 Invoker,具体实现如下:

在 getMockObject() 方法中会检查 mockService 参数是否为 true 或 default,如果是的话,则在服务接口后添加 Mock 字符串,作为服务接口的 Mock 实现;如果不是的话,则直接将 mockService 实现作为服务接口的 Mock 实现。getMockObject() 方法的具体实现如下:

本文重点介绍了 Dubbo 中 Mock 机制涉及的全部内容:

Dubbo接口中出现复杂参数,调用异常问题处理

因业务需要,原有dubbo接口参数需要扩展,并且参数格式出现多层嵌套的情况,参数Bean格式如下:

@Data

public class AddOrUpdateParam implements Serializable {

private User user;

private List<ScopeParam scopes;

}

ScopeParam定义如下:

@Data

public class ScopeParam implements Serializable {

private int identityId =0;

private List<RegionDivision regions

private List<Integer ids;

}

RegionDivision的定义如下:

@Data

public class RegionDivision implements Serializable {

private int groupID;

private int regionID;

private int regionType;

}
结果调用微服务接口时传递此参数,接口直接抛出404,纳尼,  为什么会是404?  经过查阅资料发现,dubbo参数可能太过复杂,出现了多增嵌套,导致参数解析异常,所以出现了404。既然是参数太过复杂, 那我就不传那么复杂了,直接用json格式试一下,于是直接修改定义:

private List<ScopeParam scopes ;

改为:

private String regionJson;

然后在dubbo接口内部再进行参数解析:

List<ScopeParam scopes =new ArrayList<();

if (!StringUtils.isEmpty(param.getRegionJson())) {

    MapclassMap =new HashMap();

    classMap.put("region", RegionDivision.class);

    JSONArray jsonArray =JSONArray.fromObject(param.getRegionJson());

    if (jsonArray !=null !jsonArray.isEmpty()) {

for (int i =0; i<jsonArray.size(); ++i){

ScopeParam item = (ScopeParam)JSONObject

                    .toBean(jsonArray.getJSONObject(i), ScopeParam.class, classMap);

            if (item !=null) {

scopes.add(item);

            }

}

}

}

然后再次调用,正常。 关于invoke 测试dubbo接口和dubbo测试接口调用的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。 invoke 测试dubbo接口的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于dubbo测试接口调用、invoke 测试dubbo接口的信息别忘了在本站进行查找喔。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:开源接口的测试(开源接口管理平台)
下一篇:mock一个工具类(mock一个方法)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~