dubbo學習(1)--簡單的入門搭建實例
轉載請註明源文出處: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)--簡單的入門搭建實例