-
前言
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