1. 程式人生 > >dubbo學習(1)--簡單的入門搭建實例

dubbo學習(1)--簡單的入門搭建實例

實現類 set ng- dds 更新 輸出 block sys 註冊

轉載請註明源文出處:http://www.cnblogs.com/lighten/p/6828026.html

1 簡介

dubbo是一個分布式服務框架,由阿裏巴巴的工程師開發,致力於提供高性能和透明化的RPC遠程服務調用。可惜的是該項目在2012年之後就沒有再更新了,之後由當當基於dubbo開發了dubbox。這裏對dubbo的入門構建進行簡單的介紹。不涉及dubbo的運行機制,只是搭建過程,方便學習者快速構建項目,運行、熟悉該框架。

dubbo提供了兩種構建項目的方法。1.通過Spring容器快速構建,其中還有註解的方式;2.通過直接使用API(不推薦)。以下對其一一說明。

2 前期工作

創建一個普通的maven項目,導入dubbo的依賴:

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
</dependency>

<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.4</version>
</dependency>

下載zookeeper作為註冊中心,具體步驟參考這裏。

3 Spring配置方式

3.1 生產者Provider

dubbo的生產者是用於提供服務的,先定義服務接口和服務的實現類:

public interface DemoService {
   
    public String greet(String name);
    public List<User> getUsers();
   
}

這裏有兩個服務一個是輸入一個字符串,一個是返回一個一個List對象,User類的內容如下:

public class User implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	private String name;
	private int age;
	private String sex;

	public User(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    }
}

由於接口中會傳遞一個List的User對象,所以User需要實現Serializable接口。下面是DemoServiceImpl,接口的實現類中的內容:

public class DemoServiceImpl implements DemoService{

	@Override
	public String greet(String name) {
		return "Hello " + name;
	}

	@Override
	public List<User> getUsers() {
		List<User> list = new ArrayList<User>();
        
        User user1 = new User("張三",10,"男");
        User user2 = new User("李四",11,"女");
        User user3 = new User("王五",12,"男");
        
        list.add(user1);
        list.add(user2);
        list.add(user3);
        
        return list;
	}

}

這就是一個簡單的生產者提供的服務了,和普通的服務類沒有什麽區別,關鍵是下面的dubbo配置了。與Spring結合,需要一個dubbo的配置xml文件,我命名為provider.xml,裏面的內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd 
	http://code.alibabatech.com/schema/dubbo 
	http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	
	<!-- 服務bean -->
	<bean id="demoService" class="com.xxx.dubbo.service.impl.DemoServiceImpl" />

	<dubbo:application name="provider" />
	
	<dubbo:registry address="zookeeper://127.0.0.1:2181" />
	
	<dubbo:protocol name="dubbo" port="20886" payload="16777216"/>
	
	<dubbo:service interface="com.xxx.dubbo.service.DemoService" ref="demoService" />
</beans>

上面的XML配置文件就將服務暴露出去了,將其註冊到了zookeeper中。最後運行Spring,測試:

public class Provider {

	public static void main(String[] args) throws IOException {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"provider.xml"});
		context.start();
		System.in.read();
	}
}

控制臺輸出日誌如下,就可以了:

技術分享

3.2 消費者

消費者的配置就更加簡單了,其只需要想要調用的服務的接口,在這裏就是DemoService接口,註意要確保是同一個接口。然後配置消費者的consumer.xml,配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd 
	http://code.alibabatech.com/schema/dubbo 
	http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	
	<dubbo:application name="consumer"/>
	
	<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
	
	<dubbo:reference id="demoService" interface="com.xxx.dubbo.service.DemoService" />
</beans>

reference就代表著引用一個服務,從暴露服務註冊的註冊中心獲取,在spring中就有一個這樣的接口實例了。測試類:

public class Consumer {

	public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"consumer.xml"});
        context.start();
        
        DemoService demoService = (DemoService) context.getBean("demoService");
        System.out.println(demoService.greet("張三"));
        System.out.println(demoService.getUsers());
    }
}

開啟剛剛的生產者測試類,再運行這個消費者測試類,就會看到打印出:

技術分享

3.3 註解方式

  註解的方式配置起來非常的簡單,全部如下:

[email protected],註意這個註解是com.alibaba.dubbo.config.annotation.Service,不是Spring的Service註解。

@Service
public class AnnotationProvider implements DemoService{

	@Override
	public String greet(String name) {
		return "Hello " + name;
	}

	@Override
	public List<User> getUsers() {
		List<User> list = new ArrayList<User>();
        
        User user1 = new User("張三",10,"男");
        User user2 = new User("李四",11,"女");
        User user3 = new User("王五",12,"男");
        
        list.add(user1);
        list.add(user2);
        list.add(user3);
        
        return list;
	}
}

配置文件也就是去掉了bean和<dubbo:service>,使用<dubbo:annotation>取代了:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd 
	http://code.alibabatech.com/schema/dubbo 
	http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	

	<dubbo:application name="provider" />
	
	<dubbo:registry address="zookeeper://127.0.0.1:2181" />
	
	<dubbo:protocol name="dubbo" port="20886" payload="16777216"/>
	
	<dubbo:annotation package="com.xxx.dubbo.spring.annotation.provider"/>
</beans>

消費者也相差無幾:

@Service
public class AnnotationComsumer {

	@Reference(check=false)
	private DemoService demoService;
	
	public void print() {
        System.out.println(demoService.greet("張三"));
        System.out.println(demoService.getUsers());
    }

}

註意這個Service是Spring的註解。配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd 
	http://code.alibabatech.com/schema/dubbo 
	http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	
	<dubbo:application name="consumer"/>
	
	<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
	
	<dubbo:annotation package="com.xxx.dubbo.spring.annotation.consumer" />
</beans>

啟動程序如下:

public static void main(String[] args) throws IOException {
	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"annotation-provider.xml"});
	context.start();
	System.in.read();
}

public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"annotation-consumer.xml"});
        context.start();
        AnnotationComsumer demoService =  (AnnotationComsumer) context.getBean("annotationComsumer");
        demoService.print();
}

最終效果和之前的一樣。

4. API配置方式

這個簡單說明一下,其實看API的方式和配置文件的方式就會明白一些,不做詳細介紹。

public class APIProvider {

	public static boolean running = true;
	
	public static void main(String[] args) {

        DemoService demoService = new DemoServiceImpl();
        
        ApplicationConfig applicationConfig =  new ApplicationConfig();
        applicationConfig.setName("provider");
        
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("zookeeper://127.0.0.1:2181");
        
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(20886);
        protocolConfig.setPayload(16*1024*1024);
        
        ServiceConfig<DemoService> service = new ServiceConfig<DemoService>();
        
        service.setApplication(applicationConfig);
        service.setRegistry(registryConfig);
        service.setProtocol(protocolConfig);
        service.setInterface(DemoService.class);
        service.setRef(demoService);
        
        service.export();
        
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                synchronized (APIProvider.class) {
                    running = false;
                    APIProvider.class.notify();
                }
            }
        });
        
        synchronized(APIProvider.class) {
            while(running) {
                try {
                    APIProvider.class.wait();
                } catch (Throwable e) {
                }
            }
        }
    }
}
public class APIConsumer {
    
    public static void main(String[] args) {

        ApplicationConfig applicationConfig =  new ApplicationConfig();
        applicationConfig.setName("consumer");
        

        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("zookeeper://127.0.0.1:2181");
        
        ReferenceConfig<DemoService> reference = new ReferenceConfig<DemoService>();
        reference.setApplication(applicationConfig);
        reference.setRegistry(registryConfig);
        reference.setInterface(DemoService.class);
        
        DemoService demoService = reference.get();
        System.out.println(demoService.greet("李四"));
        System.out.println(demoService.getUsers());
    }
}

都是要先定義ApplicationConfig和<dubbo:application>一致,後面RegistryConfig也一樣<dubbo:registry>。具體過程之後篇章介紹。這種API的方法不被推薦使用。

5 後記

本篇主要是幫助新手快速入門搭建一個dubbo服務,之後會從整體結構上介紹一下dubbo是如何工作的,再往後會講解一下源碼實現。水平有限,有錯請指教。

dubbo學習(1)--簡單的入門搭建實例