原文请关注微信公众号“阿甘正专”,获取更多最新文章推荐哦0.0
引言
目前微服务盛行,很多人会把Spring Cloud与Dubbo进行对比,Spring Cloud与Dubbo的比较本身是不公平的,主要是Spring Cloud提供了一套较为完整的架构方案,而Dubbo只是服务治理与RPC实现方案。
这里会通过一个简单的例子,来直观地感受Nacos服务注册中心之下,利用Dubbo来实现服务提供方与服务消费方。这里省略Nacos的安装与使用,如果对Nacos还不了解,可以查看之前发布的文章:
Spring Cloud Alibaba Nacos 0.9.0 最新实战教程(一)
Spring Cloud Alibaba Nacos 0.9.0 最新实战教程(二)– Nacos注册中心实战
1、Maven父子工程
首先构建几个SpringBoot项目,Maven父子工程,结构如下:
父pom如下:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.stwen</groupId>
<artifactId>springcloud-dubbo-nacos</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-dubbo-nacos</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<modules>
<module>spring-cloud-dubbo-api</module>
<module>spring-cloud-dubbo-provider</module>
<module>spring-cloud-dubbo-consumer</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
值得注意的是,为了方便子模块中不指定 artifactId 的版本(version),因此,还需要统一在父pom显示地声明
<dependencyManagement>
:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、spring-cloud-dubbo-api 接口模块
2.1 pom如下:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.stwen</groupId>
<artifactId>springcloud-dubbo-nacos</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.stwen</groupId>
<artifactId>spring-cloud-dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-cloud-dubbo-api</name>
<description>Demo project for Spring Boot</description>
2.2 增加一个service测试接口:
public interface ProductService {
String getProductInfo(String msg);
}
3、spring-cloud-dubbo-provider服务提供者
3.1
首先,创建 artifactId 名为 spring-cloud-dubbo-provider 的 SpringBoot模块,并在其 pom.xml 文件中增添 Dubbo Spring Cloud 必要的依赖,还有上面的api接口模块:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.stwen</groupId>
<artifactId>springcloud-dubbo-nacos</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.stwen</groupId>
<artifactId>spring-cloud-dubbo-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-cloud-dubbo-provider</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<!-- dubbo API -->
<dependency>
<groupId>com.stwen</groupId>
<artifactId>spring-cloud-dubbo-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Spring Boot dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<!-- Dubbo Spring Cloud Starter -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- Spring Cloud Nacos Service Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
以上依赖 artifact 说明如下:
-
spring-cloud-dubbo-api : 提供 ProductService 接口的 artifact。
-
spring-boot-actuator : Spring Boot Production-Ready artifact,间接引入 spring-boot artifact,否则报错。
-
spring-cloud-starter-dubbo : Dubbo Spring Cloud Starter artifact,间接引入 dubbo-spring-boot-starter 等 artifact。
-
spring-cloud-starter-alibaba-nacos-discovery : Nacos Spring Cloud 服务注册与发现 artifact。
3.2 配置文件application.yml,如下都有注释说明:
server:
port: 8081
dubbo:
scan:
# dubbo 服务扫描基准包
base-packages: com.stwen.dubbo.service
protocol:
# dubbo 协议
name: dubbo
# dubbo 协议端口( -1 表示自增端口,从 20880 开始)
port: -1
registry:
# 挂载到 Spring Cloud 注册中心
address: spring-cloud://localhost
spring:
application:
# Dubbo 应用名称
name: spring-cloud-dubbo-provider
main:
# Spring Boot 2.1 需要设定
allow-bean-definition-overriding: true
cloud:
nacos:
# Nacos 服务发现与注册配置
discovery:
server-addr: 127.0.0.1:8848
以上 YAML 内容,上半部分为 Dubbo 的配置:
-
dubbo.scan.base-packages : 指定 Dubbo 服务实现类的扫描基准包
-
dubbo.protocol : Dubbo 服务暴露的协议配置,其中子属性 name 为协议名称,port 为协议端口( -1 表示自增端口,从 20880 开始)
-
dubbo.registry : Dubbo 服务注册中心配置,其中子属性 address 的值 “spring-cloud://localhost”,说明挂载到 Spring Cloud 注册中心
-
当前 Dubbo Spring Cloud 实现必须配置 dubbo.registry.address = spring-cloud://localhost,下一个版本将其配置变为可选 (参考 issue #592), 并且支持传统 Dubbo 协议的支持(参考 issue #588)
下半部分则是 Spring Cloud 相关配置:
-
spring.application.name : Spring 应用名称,用于 Spring Cloud 服务注册和发现。
-
该值在 Dubbo Spring Cloud 加持下被视作 dubbo.application.name,因此,无需再显示地配置 dubbo.application.name
-
spring.main.allow-bean-definition-overriding : 在 Spring Boot 2.1 以及更高的版本增加该设定, 因为 Spring Boot 默认调整了 Bean 定义覆盖行为。(推荐一个好的 Dubbo 讨论 issue #3193)
-
spring.cloud.nacos.discovery : Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口
3.3 实现api的接口
@Service
public class ProductServiceImpl implements ProductService {
@Override
public String getProductInfo(String msg) {
return "hello,"+msg+",给我来100头马马哈哈!";
}
}
注:这里的@Service注解不是Spring的,而是org.apache.dubbo.config.annotation.Service注解。
4、
spring-cloud-dubbo-provider服务消费者
4.1 pom主要依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- dubbo API -->
<dependency>
<groupId>com.stwen</groupId>
<artifactId>spring-cloud-dubbo-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Spring Boot dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<!-- Dubbo Spring Cloud Starter -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- Spring Cloud Nacos Service Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
与应用 spring-cloud-dubbo-provider 不同的是,当前应用依赖 spring-boot-starter-web,表明它属于 Web Servlet 应用。
4.2 配置文件yml
Dubbo 服务消费方配置与服务提供方类似,当前应用 spring-cloud-dubbo-consumer 属于纯服务消费方,因此,所需的外部化配置更精简:
server:
port: 8082
dubbo:
registry:
# 挂载到 Spring Cloud 注册中心
address: spring-cloud://localhost
cloud:
subscribed-services: spring-cloud-dubbo-provider
spring:
application:
# Dubbo 应用名称
name: spring-cloud-dubbo-consumer
main:
# Spring Boot 2.1 需要设定
allow-bean-definition-overriding: true
cloud:
nacos:
# Nacos 服务发现与注册配置
discovery:
server-addr: 127.0.0.1:8848
对比服务提供者应用 spring-cloud-dubbo-provider,除应用名称 spring.application.name 存在差异外,spring-cloud-dubbo-client-sample 新增了属性 dubbo.cloud.subscribed-services 的设置。并且该值为服务提供方应用 “spring-cloud-dubbo-provider”。
dubbo.cloud.subscribed-services : 用于服务消费方订阅服务提供方的应用名称的列表,若需订阅多应用,使用 “,” 分割。不推荐使用默认值为 “*”,它将订阅所有应用。
当应用使用属性 dubbo.cloud.subscribed-services 默认值时,日志中将会输出一行警告:
Current application will subscribe all services(size:x) in registry, a lot of memory and CPU cycles may be used, thus it’s strongly recommend you using the externalized property ‘dubbo.cloud.subscribed-services’ to specify the services
由于当前应用属于 Web 应用,它会默认地使用 8080 作为 Web 服务端口,如果需要自定义,可通过属性 server.port 调整,这里设为8082。
4.3 编写测试controller
@RestController
public class ProductController {
@Reference(check=false)
private ProductService productService;
@GetMapping("/product")
public String getProductInfo(String msg){
return productService.getProductInfo(msg);
}
}
5、运行测试
首先运行Nacos服务,本地启动,默认为:127.0.0.1:8848
再分别启动服务提供者、消费者,然后浏览器访问:http://localhost:8082/product?msg=stwen ,如下:
以上结果说明应用
spring-cloud-dubbo-consumer
通过消费 Dubbo 服务,返回服务提供方
spring-cloud-dubbo-provider
运算后的内容。
6、小结
通过本示例,将SpringCloud与Dubbo整合,并使用Nacos作为注册中心,不用再同时兼顾Eureka与Zookeeper的配置,只需要维护好Nacos即可,并且Nacos提供友好又简洁的控制台,既可以作为注册中心,又可以当配置中心。在Spring Cloud Alibaba的整合下,使用Dubbo既可以享受到原本RPC带来的性能优势,又可以享受到Spring Cloud的各大组件的便利。总得来说,不用再纠结选择SpringCloud还是Dubbo,可以两者结合,优势互补,适应更多不同的场景。
参考官网:
https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/README_CN.md
往期推荐:
●
Spring Cloud Alibaba Nacos 配置中心对比与实战
●
Spring Cloud Alibaba 完美融合Dubbo-Nacos示例
●
SpringCloud电商秒杀微服务-Redisson分布式锁方案