公司安排学习zookeeper+dubbo的分布式服务系统,于是自己在单机上搞了个,主要是测试dubbo对并发请求以及服务端并发执行的设置的。
首先,写一个service接口与实现类,大概是hello world就不写了,提供方配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- provider's application name, used for tracing dependency relationship -->
<dubbo:application name="demo-provider"/>
<!-- use multicast registry center to export service -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- use dubbo protocol to export service on port 20880 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- service implementation, as same as regular local bean -->
<bean id="demoService" class="com.dubbo.impl.DemoServiceImpl"/>
<!-- declare the service interface to be exported -->
<dubbo:service interface="com.dubbo.DemoService" ref="demoService"/>
这是直接从官方demo拷下来的,然后消费方配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),
don't set it same as provider -->
<dubbo:application name="demo-consumer"/>
<!-- use multicast registry center to discover service -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- generate proxy for the remote service, then demoService can be used in the same way as the
local regular interface -->
<dubbo:reference id="demoService" check="false" interface="com.dubbo.DemoService" actives="10"/>
</beans>
这里在<dubbo:reference>中添加了actives="10"的参数,这是官方文档给我们的dubbo针对高并发的参数配置,max limit=10,然后我们进行测试,提供方测试文件:
import java.io.IOException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ProviderTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"dubbo-demo-provider.xml"});
context.start();
System.out.println("服务注册成功,在2181注册中心端口暴露");
try {
System.in.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
context.close();
}
}
消费方测试:
package com.dubbo;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 高并发模拟,使用CountDownLatch同步类
* @author Administrator
*
*/
public class Consumer3 {
public static void main(String[] args) {
final Integer concurrency = 100;//并发量
ExecutorService pool = Executors.newCachedThreadPool();
final AtomicInteger number = new AtomicInteger();
final CountDownLatch command = new CountDownLatch(1);
for( int i=0;i<concurrency;i++){
Runnable task = new Runnable(){
public void run() {
try {
Integer order = number.getAndIncrement();
command.await();
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"dubbo-demo-consumer.xml"});
context.start();
System.out.println(((DemoService)context.getBean("demoService")).say()+order);
System.in.read();
context.close();
} catch (Exception e) {
e.printStackTrace();
}
}
};
pool.execute(task);
}
try{
System.out.println("准备执行并发量为"+number.intValue()+"的请求");
Thread.sleep((long)Math.random() * 1000);
command.countDown();//启动开关
}catch(Exception e){
e.printStackTrace();
}
}
}
这里使用了CountDownLatch同步类来实现并发的,运行时我们发现报错了:
错误主要是:
com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method say in the service com.dubbo.DemoService. Tried 3 times of the providers [192.168.1.140:20880] (1/1) from the registry 127.0.0.1:2181 on the consumer 192.168.1.140 using the dubbo version 2.6.0. Last error is: Waiting concurrent invoke timeout in client-side for service: com.dubbo.DemoService, method: say, elapsed: 73, timeout: 0. concurrent invokes: 10. max concurrent invoke limit: 10
这说明参数配置是成功的至少,超出了设置的最大并发量,同时观察端口占有情况:
因为我们重复地消费本地的20880的dubbo服务端口,这也说明并发请求是成功的。