开发工具Idea
一、无注册中心,消费者直接调用提供者
1、工程结构如下:
dubboapi: 接口定义
provider: 服务提供者,依赖于dubboapi
consumer: 服务消费者,依赖于dubboapi
SpringBoot版本为2.2.6
2、创建dubboapi模块
里面定义了一个接口
public interface ServiceAPI { String sendMessage(String message); }
3、创建服务提供者 provider
1) 增加Dubbo引用
<dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency>
2) 创建服务实现类HelloServiceImpl
import com.alibaba.dubbo.config.annotation.Service; import com.example.dubboapi.ServiceAPI; import org.springframework.stereotype.Component; @Component @Service(interfaceClass = ServiceAPI.class) public class HelloServiceImpl implements ServiceAPI { @Override public String sendMessage(String message) { return "provider-message=" + message; } }
3) 开启Dubbo配置
@SpringBootApplication @EnableDubboConfiguration //开启Dubbo配置 public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
4) 配置如下:
spring.application.name=dubbo-spring-boot-starter spring.dubbo.server=true spring.dubbo.registry=N/A
4、服务消费之 consumer
1) 增加Dubbo引用
<dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency>
2) 消费者调用接口方法
@Component public class QuickstartConsumer { @Reference(url = "dubbo://localhost:20880") ServiceAPI serviceAPI; public void sendMessage(String message){ System.out.println(serviceAPI.sendMessage(message)); } }
3) 开启Dubbo配置,并且获得quickstartConsumer这个bean,并调用bean中的sendMessage
@SpringBootApplication @EnableDubboConfiguration public class ConsumerApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(ConsumerApplication.class, args); QuickstartConsumer quickstartConsumer = (QuickstartConsumer)run.getBean("quickstartConsumer"); quickstartConsumer.sendMessage("hello world"); } }
5、测试
1)启动provider
2)启动consumer
打印结果如下:
缺点: 无注册中心,消费者直接调用提供者。如果服务提供者迁移,将当值服务调用者不可用; 如果服务提供者增多,将不能被调用到。
参考官方文档quickstart: https://github.com/alibaba/dubbo-spring-boot-starter/blob/master/README_zh.md
二、增加Zookeeper注册中心
1、安装Zookeeper
2、provider服务修改
1) 增加 zkclient
<dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency>
2) 增加配置 spring.dubbo.registry=zookeeper://localhost:2181
spring.application.name=dubbo-spring-boot-starter spring.dubbo.server=true #spring.dubbo.registry=N/A spring.dubbo.registry=zookeeper://localhost:2181
3、Customer服务修改
1) 增加 zkclient
<dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency>
2) application.properties增加配置
spring.dubbo.registry=zookeeper://localhost:2181
3) QuickstartConsumer修改如下
@Component public class QuickstartConsumer { //@Reference(url = "dubbo://localhost:20880") @Reference ServiceAPI serviceAPI; public void sendMessage(String message){ System.out.println(serviceAPI.sendMessage(message)); } }
4、测试
1) 启动provider
2) 启动consumer
返回结果:
provider-message=hello world
三、Dubbo异步调用
1、provider工程修改
在provider工程中,增加方法sendMessage2,sleep 4秒, 修改sendMessage方法, sleep 2秒
@Component @Service(interfaceClass = ServiceAPI.class) public class HelloServiceImpl implements ServiceAPI { @Override public String sendMessage(String message) { String msg = "provider-message=" + message; System.out.println(msg); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return msg; } @Override public String sendMessage2(String message) { String msg = "provider-message2=" + message; System.out.println(msg); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } return msg; } }
2、Customer工程修改
1) 增加sendMessage2方法,并且修改超时时间为6秒
@Component public class QuickstartConsumer { //@Reference(url = "dubbo://localhost:20880") @Reference(timeout = 6000) ServiceAPI serviceAPI; public String sendMessage(String message){ String msg = serviceAPI.sendMessage(message); return msg; } public String sendMessage2(String message){ String msg = serviceAPI.sendMessage2(message); return msg; } }
2)、按原来的写法调用两个方法sendMessage和sendMessage2
public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(ConsumerApplication.class, args); QuickstartConsumer quickstartConsumer = (QuickstartConsumer)run.getBean("quickstartConsumer"); long beginTime = System.currentTimeMillis(); String send = quickstartConsumer.sendMessage("hello world"); long endTime = System.currentTimeMillis(); String send2 = quickstartConsumer.sendMessage2("hello world2"); long endTime2 = System.currentTimeMillis(); System.out.println(send + ",执行时间" + (endTime - beginTime)); System.out.println(send2 + ",执行时间" + (endTime2 - beginTime)); }
输出结果如下
provider-message=hello world,执行时间2055 provider-message2=hello world2,执行时间6061
3) 改造成异步调用
Provider工程启动异步调用
Consumer改成异步调用
public static void main(String[] args) throws ExecutionException, InterruptedException { ConfigurableApplicationContext run = SpringApplication.run(ConsumerApplication.class, args); QuickstartConsumer quickstartConsumer = (QuickstartConsumer)run.getBean("quickstartConsumer"); //测试异步调用 long beginTime = System.currentTimeMillis(); String send = quickstartConsumer.sendMessage("hello world"); Future<String> sendFuture = RpcContext.getContext().getFuture(); long endTime = System.currentTimeMillis(); String send2 = quickstartConsumer.sendMessage2("hello world2"); Future<String> sendFuture2 = RpcContext.getContext().getFuture(); long endTime2 = System.currentTimeMillis(); System.out.println( sendFuture.get() + ",执行时间" + (endTime - beginTime)); System.out.println(sendFuture2.get() + ",执行时间" + (endTime2 - beginTime)); }
输出结果如下:
provider-message=hello world,执行时间35 provider-message2=hello world2,执行时间35
可以发现,两个都是35毫秒,这时间是程序执行的时间,我们在程序中sleep的时间没有加进去