Dubbo+Zookeeper架构——springboot整合dubbo

SpringBoot与Dubbo的整合,在网上我百度到最多的会两种方式的依赖引入。

<dependency>
    <groupId>com.alibaba.spring.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>
<dependency>
    <groupId>io.dubbo.springboot</groupId>
    <artifactId>spring-boot-starter-dubbo</artifactId>
    <version>1.0.0</version>
</dependency>

不过根据更新的时间去看,我这边选用了alibaba的依赖来使用。并且ch

 

查看官网给的案例:https://github.com/apache/incubator-dubbo-spring-boot-project/blob/master/README_CN.md

项目结构:

Dubbo+Zookeeper架构——springboot整合dubbo

以上是一个简单的dubbo 和 springboot 整合的结构。

  • springboot_dubbo_luu_learing  父项目
  • luu_api   接口
  • luu_service  服务提供者
  • luu_web  服务消费者

luu_api 接口

该项目主要是用来在消费者和提供者中引用,为两者直接diao调用提供一个接口。主要是实体类对象会保存在这个项目中。也不会有过多的依赖引入。

Dubbo+Zookeeper架构——springboot整合dubbo

pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>springboot_dubbo_luu_learing</artifactId>
        <groupId>com.luu.learing</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>luu_api</artifactId>
    <packaging>jar</packaging>

    <name>luu_api</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.16</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
    </dependencies>
</project>

 

luu_service 服务消费者

目前我们没有采用自动的dubbo配置,我们是自定义配置类去对dubbo进行配置。

Dubbo+Zookeeper架构——springboot整合dubbo

pom.xml配置文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot_dubbo_luu_learing</artifactId>
        <groupId>com.luu.learing</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>luu_service</artifactId>
    <packaging>jar</packaging>
    <name>luu_service</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


        <!-- 服务监控模块 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>

        <!-- 引入spring-boot-starter以及dubbo和curator的依赖 -->
        <dependency>
            <groupId>com.alibaba.spring.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>io.dubbo.springboot</groupId>-->
            <!--<artifactId>spring-boot-starter-dubbo</artifactId>-->
            <!--<version>1.0.0</version>-->
        <!--</dependency>-->


        <!-- Spring Boot相关依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- zk服务中心 -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.12</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.2</version>
        </dependency>

        <!--Mybatis-SpringBoot集成-->
        <!--<dependency>-->
            <!--<groupId>org.mybatis.spring.boot</groupId>-->
            <!--<artifactId>mybatis-spring-boot-starter</artifactId>-->
            <!--<version>1.0.0</version>-->
        <!--</dependency>-->
        <!--<dependency>-->
            <!--<groupId>com.alibaba</groupId>-->
            <!--<artifactId>druid-spring-boot-starter</artifactId>-->
            <!--<version>1.1.0</version>-->
        <!--</dependency>-->

        <!-- mysql-connector-java -->
        <!--<dependency>-->
            <!--<groupId>mysql</groupId>-->
            <!--<artifactId>mysql-connector-java</artifactId>-->
            <!--<version>5.1.38</version>-->
        <!--</dependency>-->


        <!--luu_api服务接口-->
        <dependency>
            <groupId>com.luu.learing</groupId>
            <artifactId>luu_api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

dubbo.xml配置文件

# zk注册中心地址和端口,注册中心配置,用于配置连接注册中心相关信息。
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.registry.id=luu-service-registry

# 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。
# 当前服务/应用的名字
spring.dubbo.application.name=provider
spring.dubbo.application.id=provider

# 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
spring.dubbo.protocol.port=20991
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.id=dubbo
spring.dubbo.protocol.status=server

# 服务暴露与发现消费所在的package,这个配置只要用来扫描我们向外提供服务的实现类的包 ,开启包扫描,可替代 @EnableDubbo 注解
spring.dubbo.scan.basePackages=com.luu.learing.facadeImpl

# 这是一个我们自定义的服务版本号,可以随便写,推荐规范的书写
spring.dubbo.service.version=1.0.0

# 启动时检查
spring.dubbo.consumer.check=false

我们在 DefaultProperties 类中使用配置注解  @Configuration ,通过注解

@PropertySource(value = {"classpath:/dubbo.properties"}, ignoreResourceNotFound = true)

引入了外部属性的配置文件。并且通过注解 @ConfigurationProperties 将对应的dubbo属性值配置到类 DubboProperties

@Configuration
@PropertySource(value = {"classpath:/dubbo.properties"}, ignoreResourceNotFound = true)
public class DefaultProperties {
    @Bean
    @ConfigurationProperties(prefix = "spring.dubbo")
    public DubboProperties dubboProperties() {
        return new DubboProperties();
    }
}




package com.luu.learing.config;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;

public class DubboProperties {

    private String scan;

    private ApplicationConfig application;

    private ProtocolConfig protocol;

    private RegistryConfig registry;

    private  int timeout=3000;
    private  int  retries=3;
    private  int delay=-1;
    public String getScan() {
        return scan;
    }

    public void setScan(String scan) {
        this.scan = scan;
    }

    public ApplicationConfig getApplication() {
        return application;
    }

    public void setApplication(ApplicationConfig application) {
        this.application = application;
    }

    public ProtocolConfig getProtocol() {
        return protocol;
    }

    public void setProtocol(ProtocolConfig protocol) {
        this.protocol = protocol;
    }

    public RegistryConfig getRegistry() {
        return registry;
    }

    public void setRegistry(RegistryConfig registry) {
        this.registry = registry;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public int getRetries() {
        return retries;
    }

    public void setRetries(int retries) {
        this.retries = retries;
    }

    public int getDelay() {
        return delay;
    }

    public void setDelay(int delay) {
        this.delay = delay;
    }
}

 

之后我们自定义配置类去配置dubbo

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.AnnotationBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@SuppressWarnings("deprecation")
@Configuration
//某个class位于类路径上,才会实例化一个Bean
@ConditionalOnClass({AnnotationBean.class,ApplicationConfig.class,ProtocolConfig.class,RegistryConfig.class,ProviderConfig.class})
public class DubboAutoConfigration {

    @Bean
    @ConditionalOnMissingBean(AnnotationBean.class)//容器中如果没有这个类,那么自动配置这个类
    public static AnnotationBean annotationBean(@Value("${spring.dubbo.scan.basePackages}")String packageName) {
        System.out.println("-------------------------"+packageName+"-----------------------------");
        AnnotationBean annotationBean = new AnnotationBean();
        annotationBean.setPackage(packageName);
        return annotationBean;
    }

    @Bean
    @ConditionalOnMissingBean(ApplicationConfig.class)//容器中如果没有这个类,那么自动配置这个类
    public ApplicationConfig applicationConfig( DubboProperties prop) {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        System.out.println("----"+prop.getApplication().getName());
        applicationConfig.setName(prop.getApplication().getName());
        return applicationConfig;
    }

    @Bean
    @ConditionalOnMissingBean(ProtocolConfig.class)//容器中如果没有这个类,那么自动配置这个类
    public ProtocolConfig protocolConfig( DubboProperties prop) {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName(prop.getProtocol().getName());
        System.out.println(prop.getProtocol().getName()+"======");
        protocolConfig.setPort(prop.getProtocol().getPort());
        return protocolConfig;
    }

    @Bean
    @ConditionalOnMissingBean(RegistryConfig.class)//容器中如果没有这个类,那么自动配置这个类
    public RegistryConfig registryConfig( DubboProperties prop) {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress(prop.getRegistry().getAddress());
        return registryConfig;
    }
    @Bean
    public ProviderConfig providerConfig(ApplicationConfig applicationConfig, RegistryConfig registryConfig, ProtocolConfig protocolConfig,DubboProperties prop) {
        System.out.println("providerConfig 配置=====");
        ProviderConfig providerConfig = new ProviderConfig();
        providerConfig.setTimeout(prop.getTimeout());
        providerConfig.setRetries(prop.getRetries());
        providerConfig.setDelay(prop.getDelay());
        providerConfig.setApplication(applicationConfig);
        providerConfig.setRegistry(registryConfig);
        providerConfig.setProtocol(protocolConfig);
        return providerConfig;
    }
}

发布服务tong通过注解@Service,这个@Service是dubbo提供的注解

@Component
@Service(interfaceClass = UserInfoFacade.class)
public class UserInfoFacadeImpl implements UserInfoFacade {

    @Autowired
    private UserInfoService userInfoService;

    @Override
    public UserInfo getUserInfo() {
        return userInfoService.getUuserInfo();
    }
}

服务提供者启动类

@SpringBootApplication
@EnableAutoConfiguration
public class LuuSerApplication
{
    public static void main( String[] args )
    {
        ConfigurableApplicationContext context = SpringApplication.run(LuuSerApplication.class, args);
    }
}

 

 

luu_web 服务消费者

服务消费者的配置与服务提供者一样,除了在配置文件上有点不同之外,比如协议的端口号和名称不一样。

spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
spring.dubbo.registry.id=luu-controller-registry
spring.dubbo.protocol.port=20990
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.id=dubbo
spring.dubbo.protocol.status=server
spring.dubbo.application.name=comsumer
spring.dubbo.application.id=comsumer
spring.dubbo.scan.basePackages=com.luu.learing.controller
spring.dubbo.service.version=1.0.0
spring.dubbo.consumer.check=false

消费服务,通过注解@Reference 注解

@RestController
public class LuuController {

    @Reference
    private UserInfoFacade userInfoFacade;

    @RequestMapping("getInfo")
    public UserInfo get(){
        return userInfoFacade.getUserInfo();
    }
}

 

我们分别启用消费者和提供者,然后在管控台可以看到数据。

Dubbo+Zookeeper架构——springboot整合dubbo