1 简介
dubbo是一个分布式服务框架,由阿里巴巴的工程师开发,致力于提供高性能和透明化的RPC远程服务调用。可惜的是该项目在2012年之后就没有再更新了,之后由当当基于dubbo开发了dubbox。这里对dubbo的入门构建进行简单的介绍。不涉及dubbo的运行机制,只是搭建过程,方便学习者快速构建项目,运行、熟悉该框架。
dubbo提供了两种构建项目的方法。1.通过Spring容器快速构建,其中还有注解的方式;2.通过直接使用API(不推荐)。以下对其一一说明。
2 前期工作
创建一个普通的maven项目,导入dubbo的依赖:
com.alibaba
dubbo
2.5.3
com.101tec
zkclient
0.4
下载zookeeper作为注册中心,具体步骤参考这里。
3 Spring配置方式
3.1 生产者Provider
dubbo的生产者是用于提供服务的,先定义服务接口和服务的实现类:
public interface DemoService {
public String greet(String name);
public List 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 getUsers() {
List list = new ArrayList();
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,里面的内容如下:
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">
上面的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,配置如下:
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">
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 注解方式
注解的方式配置起来非常的简单,全部如下:
生产者就是实现类上打上@Service注解就可以了,注意这个注解是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 getUsers() {
List list = new ArrayList();
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和,使用取代了:
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">
消费者也相差无几:
@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的注解。配置文件如下:
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">
启动程序如下:
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 service = new ServiceConfig();
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 reference = new ReferenceConfig();
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和一致,后面RegistryConfig也一样。具体过程之后篇章介绍。这种API的方法不被推荐使用。
5 后记
本篇主要是帮助新手快速入门搭建一个dubbo服务,之后会从整体结构上介绍一下dubbo是如何工作的,再往后会讲解一下源码实现。水平有限,有错请指教。