1. 程式人生 > >單機模式模擬併發消費dubbo服務

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