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的生产者是用于提供服务的,先定义服务接口和服务的实现类:
1 2 3 4 5 6 | public interface DemoService { public String greet(String name); public List<User> getUsers(); } |
这里有两个服务一个是输入一个字符串,一个是返回一个一个List对象,User类的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 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,接口的实现类中的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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,里面的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?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,测试:
1 2 3 4 5 6 7 8 | 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,配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?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中就有一个这样的接口实例了。测试类:
1 2 3 4 5 6 7 8 9 10 11 | 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注解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @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>取代了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?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> |
消费者也相差无几:
1 2 3 4 5 6 7 8 9 10 11 12 | @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的注解。配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?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> |
启动程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 | 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的方式和配置文件的方式就会明白一些,不做详细介绍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | 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) { } } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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是如何工作的,再往后会讲解一下源码实现。水平有限,有错请指教。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步