接上文,了解Dubbo接口后,如何测试dubbo接口:
Python版解决方案:
1. hessian+http的方式调用(python-hessian库):
(1) dubbo项目中,增加hessian方式序列化,及相关依赖。下图为xml配置方式示例。
(2) 获取接口地址(可在管理台查看)、方法及方法的入参。
(3) 安装 python-hessian
1
python -m pip install python-hessian
(4) 编写Python脚本调用接口; pyhessian官方调用例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28# coding=utf-8
import pytest
from pyhessian.client import HessianProxy
class TestDubbo(object):
url = "http://169.254.210.145:1234/"
interface = "com.xxx.user.service.UserService"
full_url = url + interface
# full_url = "http://169.254.210.145:8888/com.xxx.user.service.FileService"
def testsayHelloWithSpec(self):
params = u"什么我调用成功了吗"
# 创建连接对象
service = HessianProxy(self.full_url)
# 重载方法__call()__里发送二进制数据进行请求,调用方法
res = service.sayHello(params)
assert "什么我调用成功了吗" in res
print(res)
# @pytest.mark.skip()
def testsayHelloWithInt(self):
params = 123
service = HessianProxy(self.full_url)
res = service.sayHello(params)
assert 123 in res
print(res)
if __name__ == "__main__":
pytest.main(["-q","TestDubbo.py"])
2. 使用dubbo-client
- dubbo项目中,provicer.xml 增加 jsonrpc 协议
- 官方地址
其他参考示例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18config = ApplicationConfig('test_rpclib')
service_interface = 'com.ofpay.demo.api.UserProvider'
# Contains a connection to zookeeper, which needs caching.
registry = ZookeeperRegistry('192.168.59.103:2181', config)
user_provider = DubboClient(service_interface, registry, version='1.0')
for i in range(1000):
try:
print user_provider.getUser('A003')
print user_provider.queryUser(
{u'age': 18, u'time': 1428463514153, u'sex': u'MAN', u'id': u'A003', u'name': u'zhangsan'})
print user_provider.queryAll()
print user_provider.isLimit('MAN', 'Joe')
print user_provider('getUser', 'A005')
except DubboClientError, client_error:
print client_error
time.sleep(5)
java:
1. XML配置文件方式:
- 拿到服务的jar包或maven依赖
- 在resources下创建consumer.xml,配置好注册中心地址,接口名全称(有包名限定),每个接口有其唯一的标识reference id
- 调用测试方法中,使用springframework提供的方法加载consumer.xml配置文件,得到context对象,调用start方法启动
- 调用context对象的getBean方法,传入接口标识作为实参,获取接口的具体实现对象,这步会进行远程过程调用
- 通过获取的对象调用其提供的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31import com.xxx.user.service.UserService;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
public class ConsumerTest {
static ClassPathXmlApplicationContext context;
static UserService userService;
public static void beforeClass(){
if(context==null) {
// 默认从类路径中加载配置文件
context = new ClassPathXmlApplicationContext("consumer.xml");
System.out.println("load");
// 在Spring中还提供了Lifecycle接口,Lifecycle中包含start/stop方法,实现此接口后Spring保证在启动的时候调用其start方法开始生命周期,主要用于控制异步处理过程
context.start();
// System.out.println("start");
}
// 创建接口实例(定义接口的引用变量,再引用实现了该接口的实例)
userService=(UserService) context.getBean("userService");
}
public void consumerTestCase1(){
// 调用方法
String hello = userService.sayHello("world");
assertThat(hello,containsString("world");
System.out.println(hello);
}
}
2. API方式的泛化调用:
- 不需要获取被测接口的jar包或依赖
- 官方示例1
官方示例2 - 创建连接实例:
- 使用 org.apache.dubbo.config.ApplicationConfig 配置消费者应用名
- 使用 org.apache.dubbo.config.ReferenceConfig; 创建reference配置实例,设置接口全类名,声明泛化调用,配置消费者
- 使用org.apache.dubbo.config.RegistryConfig; 配置注册中心地址
- 调用reference配置实例的get方法,获取GenericService类型的连接实例
- 调用服务提供的方法:
- 调用org.apache.dubbo.rpc.service.GenericService 这个接口名为 $invoke方法,它接受三个参数,分别为方法名、方法参数类型数组和参数值数组;
- 对于方法参数类型数组:
- 如果是基本类型,如 int 或 long,可以使用 int.class.getName()获取其类型;
- 如果是基本类型数组,如 int[],则可以使用 int[].class.getName();
- 如果是 POJO,则直接使用全类名,如 com.alibaba.dubbo.samples.generic.api.Params。
- 参数值数组:
- 如果是POJO,则转成Map,再将转换后的Map作为参数传入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void test2(){
ApplicationConfig application = new ApplicationConfig();
application.setName("api-generic-consumer");
// 使用RegistryConfig,动态配置注册中心地址
RegistryConfig registry = new RegistryConfig();
registry.setAddress("zookeeper://127.0.0.1:2181");
application.setRegistry(registry);
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
// 弱类型接口名
reference.setInterface("com.ymxdclass.user.service.UserService");
// 声明为泛化接口
reference.setGeneric(true);
reference.setApplication(application);
// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
GenericService genericService = reference.get();
String name = (String) genericService.$invoke("sayHello", new String[]{String.class.getName()}, new Object[]{"who am i"});
System.out.println(name);
}
- 如果是POJO,则转成Map,再将转换后的Map作为参数传入
- 对于方法参数类型数组:
- 调用org.apache.dubbo.rpc.service.GenericService 这个接口名为 $invoke方法,它接受三个参数,分别为方法名、方法参数类型数组和参数值数组;