單機模式模擬併發消費dubbo服務
公司安排學習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服務埠,這也說明併發請求是成功的。