开发工具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的时间没有加进去