-
前言
Spring Cloud是一个较为全面的微服务框架集,集成了如服务注册发现、配置中心、消息总线、负载均衡、断路器、API网关等功能实现。而在网上经常会发现Spring Cloud与阿里巴巴的Dubbo进行选择对比,这样做其实不是很妥当,前者是一套较为完整的架构方案,而Dubbo只是服务治理与RPC实现方案。
Dubbo在国内有着非常大的用户群体,但是其周边设施与组件相对来说并不那么完善。很多开发者用户又很希望享受Spring Cloud的生态,因此也会有一些Spring Cloud与Dubbo一起使用的案例与方法出现,但是一直以来大部分Spring Cloud整合Dubbo的使用方案都不完善。直到Spring Cloud Alibaba的出现,才得以解决这样的问题。
在此之前,我们已经学了如何使用Spring Cloud Alibaba来集成Nacos与Spring Cloud应用,并且在此之下可以如传统的Spring Cloud应用一样地使用Ribbon或Feign来微服务之间的协作。由于Feign是基于Http Restful的调用,在高并发下的性能不够理想,RPC方案能否切换为Dubbo?Spring Cloud与阿里系的若干组件能否完美集成呢?
可以!本章内容将指引大家集成一个微服务的基础架构,并讨论其合理性。
-
系统架构图
API网关 :系统统一入口,屏蔽架构内部结构,统一安全拦截,采用Zuul实现。
application-1 :应用1,模拟应用,提供http接口服务。
service-1 :微服务1,模拟微服务,提供dubbo接口服务。
service-2 :微服务2,模拟微服务,提供dubbo接口服务。
调用流程:
所有访问系统的请求都要经过网关,网关转发Http请求至application-1,application-1使用dubbo调用service1完成自身业务,而后sevice1调用service2完成自身业务。至此,完成所有组件贯穿。
application与sevice的区别是什么?
- service提供了基础服务功能;application组装基础服务功能,提供给用户直接可用的业务。
- service服务粒度小、功能基础,不易发生改变;application提供上游业务功能,紧贴业务需求,容易发生改变。
- 形成service支撑application的整体架构,增加多变的application甚至不需要变动service。
-
工程结构
nacos‐micro‐service 整体父工程
├─api‐gateway API网关,端口:56010
├─application‐1 应用1,端口:56020
├─service‐1 服务1父工程
│ ├─service‐1‐api 服务1API
│ └─service‐1‐server 服务1实现,端口:56030
└─service‐2 服务2父工程
├─service‐2‐api 服务2API
└─service‐2‐server 服务2实现,端口:56040
application‐1 应用1,端口:56020
pom.xml
<?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>nacos‐micro‐service</artifactId>
<groupId>com.zeng</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>application‐1</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--需要引入该jar才能使bootstrap配置文件生效-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
</project>
bootstrap.yml
server: port: 56020 #启动端口 命令行注入 servlet: context‐path: /application1 spring: application: name: application1 main: allow‐bean‐definition‐overriding: true # Spring Boot 2.1 需要设定 cloud: nacos: discovery: server-addr: 192.168.31.119:8848 namespace: 405e2609-c439-4b1e-b177-82f5a5ce2a0b config: server-addr: 192.168.31.119:8848 file-extension: yaml namespace: 405e2609-c439-4b1e-b177-82f5a5ce2a0b group: TEST_GROUP
测试controller
@RestController
public class Application1Controller {
@GetMapping("/service")
public String service(){
return "test" ;
}
}
启动类
@SpringBootApplication
@EnableDiscoveryClient
public class Application1Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Application1Bootstrap.class,args);
}
}
测试
注:目前只是一个普通的spring cloud应用
service‐1
service-1-api只是一个普通maven工程,所以就不赘述了
pom.xml
<?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>Service1</artifactId>
<groupId>com.zeng</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-1-server</artifactId>
<dependencies>
<dependency>
<groupId>com.zeng</groupId>
<artifactId>service-1-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--需要引入该jar才能使bootstrap配置文件生效-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
</dependencies>
</project>
@org.apache.dubbo.config.annotation.Service
public class ConsumerServiceImpl implements ConsumerService {
@Override
public String service() {
return "Consumer invoke ";
}
}
@SpringBootApplication
@EnableDiscoveryClient
public class Service1Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Service1Bootstrap.class,args);
}
}
server: port: 56030 #启动端口 命令行注入 spring: application: name: service1 main: allow‐bean‐definition‐overriding: true # Spring Boot 2.1 需要设定 cloud: nacos: discovery: server-addr: 192.168.31.119:8848 namespace: 405e2609-c439-4b1e-b177-82f5a5ce2a0b config: server-addr: 192.168.31.119:8848 file-extension: yaml namespace: 405e2609-c439-4b1e-b177-82f5a5ce2a0b group: TEST_GROUP dubbo: scan: base-packages: com.zeng protocol: name: dubbo port: 20881 registry: address: nacos://192.168.31.119:8848 application: qos-enable: false #dubbo运维服务是否开启 consumer: check: false #启动时就否检查依赖的服务
注意:使用org.apache.dubbo.config.annotation.Service注解来暴露服务
-
实现 application1调用Service1
pom增加如下依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.zeng</groupId>
<artifactId>service-1-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
@RestController
public class Application1Controller {
@Reference
private ConsumerService consumerService;
@GetMapping("/service")
public String service(){
return "Application1 "+consumerService.service() ;
}
}
注意:使用org.apache.dubbo.config.annotation.Reference注解引用服务
-
测试
service-2-api和service-2-server同理,请参考service-1-api和service-1-server
service1调用service2
在service1的pom中增加如下依赖
<dependency>
<groupId>com.zeng</groupId>
<artifactId>service‐2‐api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
修改controller
@org.apache.dubbo.config.annotation.Service
public class ConsumerServiceImpl implements ConsumerService {
@org.apache.dubbo.config.annotation.Reference
private ProviderService providerService;
@Override
public String service() {
return "Consumer invoke | "+providerService.service();
}
}
测试:
这样便实现了application1调用service1,service1调用service2的流程
-
搭建网关工程实现api-gateway
pom.xml
<?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>nacos‐micro‐service</artifactId>
<groupId>com.zeng</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api‐gateway</artifactId>
<dependencies>
<!--需要引入该jar才能使bootstrap配置文件生效-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class ApiGatewayBootstrap {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayBootstrap.class, args);
}
}
bootstrap.yml
server: port: 56010 #启动端口 命令行注入 spring: application: name: apiGateway main: allow‐bean‐definition‐overriding: true # Spring Boot 2.1 需要设定 cloud: nacos: discovery: server-addr: 192.168.31.119:8848 namespace: 405e2609-c439-4b1e-b177-82f5a5ce2a0b config: name: api-gateway server-addr: 192.168.31.119:8848 file-extension: yaml namespace: 405e2609-c439-4b1e-b177-82f5a5ce2a0b group: TEST_GROUP
zull的配置在nacos上
zuul: routes: application1: stripPrefix: false path: /application1/**
启动类运行后测试:
通过网关(api-gateway)请求Application1应用,Application1的业务实现又贯穿service1、service2,至此,路由成功!!!
-
附上配置项信息说明
示例代码链接: https://pan.baidu.com/s/1ZhH6UiuuT1NHk0102c9YDg