work hard work smart

专注于Java后端开发。 不断总结,举一反三。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SpringBoot集成Dubbo实践

Posted on 2020-05-06 16:17  work hard work smart  阅读(483)  评论(0编辑  收藏  举报

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