天天看点

Spring Boot 进阶-SpringBoot如何整合Apache Dubbo详解

作者:架构师面试宝典
Spring Boot 进阶-SpringBoot如何整合Apache Dubbo详解

首先我们知道Apache Dubbo 是不需要Spring Boot的依赖也可以完成微服务架构的支持与搭建工作,这个是由于在Apache Dubbo中本身就具有Spring相关的依赖,而Spring Boot也是依赖于Spring 来进行实现的。既然两者都是基于Spring实现,那么两者的结合一定会有意想不到的效果。

由于Dubbo被重启的时候,无论是Spring Boot还是Dubbo都没有现在这么成熟的生态,所以说整合起来比较麻烦,但是现在随着微服务生态体系的不断完成使用Spring Boot 整合Apache Dubbo来实现微服务操作的应用也越来越多,在加上Spring Boot 自动装配等优势,二者结合也是极大地提升了开发的效率。下面我们就来通过一个简单的小例子来演示一下如何将Spring Boot 与Apache Dubbo进行整合。

创建一个服务提供者

第一步,我们需要创建一个普通的Maven工程与之前一样,命名为dubbo-spring-boot-provider,并且在这个Maven项目中我们还要提供两个模块一个是服务模块、一个是接口模块,分别命名为user-service和user-api,目录结构如下图所示。

Spring Boot 进阶-SpringBoot如何整合Apache Dubbo详解

第二步,在user-api模块中定义一个HelloWorld的测试接口,用来进行远程调用相关的测试工作,然后在通过mvn install命令将其创建到本地的Maven私服中,以便其他项目的引用。

public interface IHelloService {
   
    public String hello(String name);
}
           

第三步,需要在user-service模块中引入一些Spring Boot以及Apache Dubbo相关的依赖,这里有一点需要说明,就是在笔者演示的时候用的可能不是最新的依赖版本,但是原理是一样的。

<?xml version="1.0" encoding="UTF-8"?>
<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>dubbo-spring-boot-provider</artifactId>
        <groupId>com.provider</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-service</artifactId>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.7.5</version>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.5</version>
        </dependency>

        <dependency>
            <groupId>com.provider</groupId>
            <artifactId>user-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>           

第四步,在完成了依赖引入之后,我们就需要在user-provider中实现上面定义的接口,在这里我们使用SPEL表达式获取到对应服务的名称,用来标识我们的服务调用是否正常执行,

@Service
public class HelloServiceImpl implements IHelloService {

    @Value("${dubbo.application.name}")
    private String serviceName;

    public String hello(String name) {
        return serviceName + "say Hello "+name;
    }
}
           

这里我们注意到在这个实现类上我们标注的@Service注解是来自Dubbo的Service注解。import org.apache.dubbo.config.annotation.Service; 而不是在Spring Boot中提供的@Service注解。这一点在引入的时候需要注意。

第五步,完成上面的配置之后,我们需要在application.properties配置文件中加入Dubbo的相关配置服务信息。

spring.application.name=dubbo-spring-boot-provider
dubbo.application.name=user-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.registry.address=N/A           

第六步,添加完配置依赖之后我们就需要创建一个主启动类来启动我们的服务提供者

@DubboComponentScan
@SpringBootApplication
public class DubboProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(DubboProviderApplication.class,args);
    }
}
           

这里我们需要注意的是,在这个主启动类上有一个 @DubboComponentScan 注解,这个注解的意思就是扫描当前路径,以及其子路径下所有的关于Dubbo的相关注解。例如上面的@Service注解,就是来自Dubbo提供的服务注解。

创建一个服务消费者

根据上面的逻辑,我们需要创建一个服务消费者用来进行服务的调用操作。

第一步,这次我们来创建一个Spring Boot的项目dubbo-spring-boot-consumer,并且添加相关的依赖。

<dependency>
	<groupId>org.apache.dubbo</groupId>
	<artifactId>dubbo-spring-boot-starter</artifactId>
	<version>2.7.5</version>
</dependency>

<dependency>
	<groupId>com.provider</groupId>
	<artifactId>user-api</artifactId>
	<version>1.0-SNAPSHOT</version>
</dependency>           

第二步,添加完依赖之后,在consumer项目中添加配置文件

dubbo.application.name=dubbo-consumer           

第三步,完成配置之后,在主启动类中完成如下的配置

@SpringBootApplication
public class DubboSpringBootConsumerApplication {


	@Reference(url = "dubbo://192.168.3.21:8080/com.provider.service.IHelloService")
	private IHelloService helloService;

	public static void main(String[] args) {
		SpringApplication.run(DubboSpringBootConsumerApplication.class, args);
	}

	@Bean
	public ApplicationRunner runner(){
		return args -> System.out.println(helloService.hello("架构师"));
	}

}           

首先我们需要通过@Reference注解来引入服务提供者的调用,其次通过如下的代码对服务提供者进行远程调用操作调用,这里只是简单的演示了调用者,在实际开发的过程中我们可以通过Controller层的封装进行调用。

@Bean
	public ApplicationRunner runner(){
		return args -> System.out.println(helloService.hello("架构师"));
	}           

使用@RestController进行封装,首先需要在Consumer下创建一个Controller。然后对调用对象进行引入。

@RestController
public class HelloController {
    @Reference(url = "dubbo://192.168.3.21:8080/com.provider.service.IHelloService")
    private IHelloService helloService;
    
    
    @GetMapping("/hello")
    public String hello(){
        return helloService.hello("架构师");
    }
}           

到这里我们就分别完成了服务提供者和服务调用者的开发工作。然后在本地启动Dubbo相关的服务就可以完成服务的调用操作。

总结

相比于通过XML的方式进行服务注册来讲,通过注解的方式更加简单明了,不但提升了开发效率,还在一定程度上简化的代码的开发。另外Dubbo官方还提供了基于Dubbo的服务检测模块,引入该模块之后可以针对各种服务进行一个监控。这也是提供了服务高可用健康检查的更加高效的解决方案。