Spring Cloud Alibaba架構實戰

Spring Cloud Alibaba 架構實戰

視頻:https://blog.csdn.net/weixin_44062339/article/details/103394897
完整講義:http://www.pbteach.com/post/java_distribut/nacos-discovery/
http://www.pbteach.com/post/java_distribut/nacos-config/
代碼:
鏈接:https://pan.baidu.com/s/1jweoGABWxrtF9WUOAtxQaQ
提取碼:sgxx

​ 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與阿里系的若干組件能否完美集成呢?本章內容將指引大家集成一個微服務的基礎架構,並討論其合理性。

1 總體結構

系統架構圖如下:

1571732038130

組件說明:

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。

2 工程結構說明

採用maven工程,結構如下:

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

3 創建父工程

​ 創建 artifactId 名爲 nacos-micro-service 的 Maven 工程,此父工程繼承nacos-discovery父工程,間接指定了Spring boot、spring cloud 以及spring-cloud-alibaba的依賴版本。

    <parent>
        <artifactId>nacos-discovery</artifactId>
        <groupId>com.pbteach.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>nacos-micro-service</artifactId>
    <packaging>pom</packaging>

nacos-discovery的pom.xml如下:

<groupId>com.pbteach.nacos</groupId>
<artifactId>nacos-discovery</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<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>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

4 實現application1

application1屬於應用層,提供http接口服務。

(1)初始化 application-1 Maven 工程

<artifactId>application-1</artifactId>
<dependencies>
    <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>
</dependencies>

(2)實現 application-1 功能

package com.pbteach.microservice.application1.controller;

@RestController
public class Application1Controller {

    @GetMapping("/service")
    public String service(){
       return "test" ;
    }
}

(3) application1 配置

純粹的dubbo服務消費者,配置看起來更簡單。

定義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: 127.0.0.1:8848
        namespace: c67e4a97-a698-4d6d-9bb1-cfac5f5b51c4
        cluster-name: DEFAULT
      config:
        server-addr: 127.0.0.1:8848 # 配置中心地址
        file-extension: yaml
        namespace: c67e4a97-a698-4d6d-9bb1-cfac5f5b51c4 # 開發環境
        group: NACOS_MICROSERVICE_GROUP # xx業務組


(4) application1 啓動

@SpringBootApplication
@EnableDiscoveryClient
public class Application1Bootstrap {
    public static void main(String[] args) {
        SpringApplication.run(Application1Bootstrap.class,args);
    }
}

Service1Bootstrap 啓動後,應用 application1 將出現在 Nacos 控制檯界面。

5 實現 Service1

5.1 定義父工程

定義service1父工程,pom.xml如下:

<parent>
    <artifactId>nacos-micro-service</artifactId>
    <groupId>com.pbteach.nacos</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>Service1</artifactId>

5.2 定義service-1-api

爲了方便其它服務調用dubbo服務,專門定義api工程,此工程將作爲jar被其它工程依賴。

定義service-1-api工程,pom.xml如下:

<parent>
    <artifactId>Service1</artifactId>
    <groupId>com.pbteach.nacos</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>service-1-api</artifactId>

定義服務接口:

package com.pbteach.microservice.service1.api;

public interface ConsumerService {
    public String service();
}

5.3 實現service-1-server

(1)初始化 service-1-server Maven 工程

與服務提供方 Maven工程類似,需添加相關 Maven 依賴:

	<parent>
        <artifactId>Service1</artifactId>
        <groupId>com.pbteach.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-1-server</artifactId>
<dependencies>
    <dependency>
        <groupId>com.pbteach.nacos</groupId>
        <artifactId>service-1-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

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

(2)實現 Dubbo 服務

package com.pbteach.microservice.service1.service;
@org.apache.dubbo.config.annotation.Service
public class ConsumerServiceImpl implements ConsumerService {

    @Override
    public String service() {
        return "Consumer invoke " ;
    }
}

注意:使用@org.apache.dubbo.config.annotation.Service標記dubbo服務

(3)配置 Dubbo 服務

Service2 作爲Dubbo服務消費方配置與服務提供方類似,注意,service1不僅是消費方,同時還是服務提供方:

server:
  port: ${port:56030} #啓動端口 命令行注入

spring:
  application:
    name: service1
  main:
    allow-bean-definition-overriding: true # Spring Boot 2.1 需要設定
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: c67e4a97-a698-4d6d-9bb1-cfac5f5b51c4
        cluster-name: DEFAULT
      config:
        server-addr: 127.0.0.1:8848 # 配置中心地址
        file-extension: yaml
        namespace: c67e4a97-a698-4d6d-9bb1-cfac5f5b51c4 # 開發環境
        group: NACOS_MICROSERVICE_GROUP # xx業務組
dubbo:
  scan:
    # dubbo 服務掃描基準包
    base-packages: com.pbteach.microservice
  protocol:
    # dubbo 協議
    name: dubbo
    # dubbo 協議端口
    port: ${dubbo_port:20881}
  registry:
    address: nacos://127.0.0.1:8848
  application:
    qos-enable: false #dubbo運維服務是否開啓
  consumer:
    check: false  #啓動時就否檢查依賴的服務

以上 YAML 內容,dubbo開頭的爲dubbo服務 的配置:

  • dubbo.scan.base-packages : 指定 Dubbo 服務實現類的掃描基準包,將@org.apache.dubbo.config.annotation.Service註解標註的service暴露爲dubbo服務。

  • dubbo.protocol : Dubbo 服務暴露的協議配置,其中子屬性 name 爲協議名稱,port 爲dubbo協議端口

    可以指定多協議,如:dubbo.protocol.rmi.port=1099

  • dubbo.registry : Dubbo 服務註冊中心配置,其中子屬性 address 的值 “nacos://127.0.0.1:8848”,說明dubbo服務註冊到nacos

    相當於原生dubbo的xml配置中的 <dubbo:registry address="10.20.153.10:9090" />

上半部分爲SpringCloud的相關配置:

  • spring.application.name : Spring 應用名稱,用於 Spring Cloud 服務註冊和發現。

該值在 Dubbo Spring Cloud 加持下被視作 dubbo.application.name,因此,無需再顯示地配置 dubbo.application.name

  • spring.cloud.nacos.discovery : Nacos 服務發現與註冊配置,其中子屬性 server-addr 指定 Nacos 服務器主機和端口

  • spring.cloud.nacos.config : Nacos 配置中心配置,其中子屬性 server-addr 指定 Nacos 服務器主機和端口。

(4)啓動服務消費方應用

@SpringBootApplication
@EnableDiscoveryClient
public class Service1Bootstrap {
    public static void main(String[] args) {
        SpringApplication.run(Service1Bootstrap.class, args);
    }
}

Service1Bootstrap 啓動後,應用 service1 將出現在 Nacos 控制檯界面。

啓動成功,觀察nacos服務列表

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-RK8sIFvq-1575467002609)(1572439366107.png)]

6 實現 application1調用Service1

現在service1已暴露dubbo服務並註冊到nacos中,下邊實現application1調用service1

6.1 引用service1

下邊在application1中引用service1

在pom.xml中引入service-1-api的依賴

<dependency>
    <groupId>com.pbteach.nacos</groupId>
    <artifactId>service-1-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

引入 spring-cloud-starter-dubbo依賴,它會根據接口生成代理對象

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>

6.2 實現遠程調用

@RestController
public class Application1Controller {

    @org.apache.dubbo.config.annotation.Reference
    private ConsumerService consumerService;

    @GetMapping("/service")
    public String service(){
        return "test" + consumerService.service();
    }
}

Note:注意:這裏的@Reference註解是org.apache.dubbo.config.annotation.Reference

測試:

請求:http://localhost:56020/application1/service

consumerService正常生成代理對象,service1被調用。

7 實現 Service2

​ 如上面設計所示,Service2需要暴露dubbo接口以供service1消費,若想在Spring cloud Alibaba中集成並使用dubbo。

7.1 定義父工程

定義service2父工程,pom.xml如下:

<parent>
    <artifactId>nacos-micro-service</artifactId>
    <groupId>com.pbteach.nacos</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>Service2</artifactId>

7.2 定義service-2-api

​ 定義service-2-api工程,pom.xml如下:

<parent>
    <artifactId>Service2</artifactId>
    <groupId>com.pbteach.nacos</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>service-2-api</artifactId>

​ 並定義服務接口,Dubbo 服務接口是服務提供方與消費方的遠程通訊契約,通常由普通的 Java 接口(interface)來聲明,如 ProviderService 接口:

package com.pbteach.microservice.service2.api;
public interface ProviderService {
    String service();
}

7.3 實現service-2-server

(1)初始化 service-2-server Maven 工程

首先,創建 artifactId 名爲 service-2-server 的 Maven 工程,並在其 pom.xml 文件中增添 Dubbo Spring Cloud 必要的依賴:

     <parent>
        <artifactId>Service2</artifactId>
        <groupId>com.pbteach.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-2-server</artifactId>
<dependencies>
    <dependency>
        <groupId>com.pbteach.nacos</groupId>
        <artifactId>service-2-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <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>

以上依賴 artifact 說明如下:

  • service-2-api : 提供 ProviderService 接口的 artifact
  • spring-boot-starter-web : Spring Boot starter 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

(2)實現 Dubbo 服務

ProviderService 作爲暴露的 Dubbo 服務接口,服務提供方 service-2-server 需要將其實現:

package com.pbteach.microservice.service2.service;

@org.apache.dubbo.config.annotation.Service
public class ProviderServiceImpl implements ProviderService {
    @Override
    public String service() {
        return "Provider invoke";
    }
}

其中,@org.apache.dubbo.config.annotation.Service 是 Dubbo 服務註解,僅聲明該 Java 服務(本地)實現爲 Dubbo 服務。 因此,下一步需要將其配置 Dubbo 服務(遠程)。

(3)配置 Dubbo 服務

在暴露 Dubbo 服務方面,推薦開發人員外部化配置的方式,即指定 Java 服務實現類的掃描基準包。

Dubbo Spring Cloud 繼承了 Dubbo Spring Boot 的外部化配置特性,也可以通過標註 @DubboComponentScan 來實現基準包掃描。

同時,Dubbo 遠程服務需要暴露網絡端口,並設定通訊協議,完整的 YAML 配置如下所示:

server:
  port: ${port:56040} #啓動端口 命令行注入
spring:
  application:
    name: service2
  main:
    allow-bean-definition-overriding: true # Spring Boot 2.1 需要設定
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: c67e4a97-a698-4d6d-9bb1-cfac5f5b51c4
        cluster-name: DEFAULT
      config:
        server-addr: 127.0.0.1:8848 # 配置中心地址
        file-extension: yaml
        namespace: c67e4a97-a698-4d6d-9bb1-cfac5f5b51c4 # 開發環境
        group: NACOS_MICROSERVICE_GROUP # xx業務組
dubbo:
  scan:
    # dubbo 服務掃描基準包
    base-packages: com.pbteach.microservice
  protocol:
    # dubbo 協議
    name: dubbo
    # dubbo 協議端口( -1 表示自增端口,從 20880 開始)
    port: ${dubbo_port:20891}
  registry:
    address: nacos://127.0.0.1:8848
  application:
    qos-enable: false
  consumer:
    check: false

(4)啓動服務提供方應用

Dubbo Spring Cloud 引導類與普通 Spring Cloud 應用並無差別,如下所示:

@SpringBootApplication
@EnableDiscoveryClient
public class Service2Bootstrap {
    public static void main(String[] args) {
        SpringApplication.run(Service2Bootstrap.class, args);
    }
}

在引導 Service2Bootstrap 之前,請提前啓動 Nacos 服務器。 當 Service2Bootstrap 啓動後,應用 service2 將出現在 Nacos 控制檯界面。

8 實現service1調用service2

8.1 引用service2

在service2中添加service1的依賴:

<dependency>
    <groupId>com.pbteach.nacos</groupId>
    <artifactId>service-2-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

8.2 實現遠程調用

@org.apache.dubbo.config.annotation.Service
public class ConsumerServiceImpl implements ConsumerService {

    @Reference
    ProviderService providerService;

    public String service() {
        return "Consumer invoke | "+providerService.service();
    }
}

測試:

請求:http://localhost:56020/application1/service

application1調用service1,service1調用service2

9 實現api-gateway

9.1 Zuul介紹

什麼是網關?

​ 原來的單體架構,所有的服務都是本地的,UI可以直接調用,現在按功能拆分成獨立的服務,跑在獨立的一般都在獨立的虛擬機上的 Java進程了。客戶端UI如何訪問?他的後臺有N個服務,前臺就需要記住管理N個服務,一個服務下線/更新/升級,前臺就要重新部署,這明顯不服務我們拆分的理念,特別當前臺是移動應用的時候,通常業務變化的節奏更快。另外,N個小服務的調用也是一個不小的網絡開銷。

1571880838542

​ 有了網關作爲服務統一入口,就可以避免上述問題,不僅如此,服務網關是在微服務前邊設置一道屏障,請求先到服務網關,網關會對請求進行過慮、校驗、路由等處理。有了服務網關可以提高微服務的安全性,網關校驗請求的合法性,請求不合法將被攔截,拒絕訪問。

  • 提供統一服務入口,讓微服務對前臺透明
  • 聚合後臺的服務,節省流量,提升性能
  • 提供安全,過濾,流控等API管理功能

什麼是Zuul?

​ Spring Cloud Zuul是整合Netflix公司的Zuul開源項目實現的微服務網關,它實現了請求路由、負載均衡、校驗過慮等 功能。

官方:https://github.com/Netflix/zuul

Zuul與Nginx怎麼配合使用?

Zuul與Nginx在實際項目中需要配合使用,如下圖,Nginx的作用是反向代理、負載均衡,Zuul的作用是保障微服務的安全訪問,攔截微服務請求,校驗合法性及負載均衡。

1571881971066

9.2 搭建網關工程

初始化 api-gateway Maven 工程

    <parent>
        <artifactId>nacos-micro-service</artifactId>
        <groupId>com.pbteach.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>api-gateway</artifactId>
<dependencies>
    <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>

9.3 api-gateway配置

server:
  port: 56010 #啓動端口 命令行注入

spring:
  application:
    name: api-gateway
  main:
    allow-bean-definition-overriding: true # Spring Boot 2.1 需要設定
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: c67e4a97-a698-4d6d-9bb1-cfac5f5b51c4
        cluster-name: DEFAULT
      config:
        server-addr: 127.0.0.1:8848 # 配置中心地址
        file-extension: yaml
        namespace: c67e4a97-a698-4d6d-9bb1-cfac5f5b51c4 # 開發環境
        group: NACOS_MICROSERVICE_GROUP # xx業務組

​ 網關的路由配置採用nacos遠程配置,在nacos控制檯開發環境中新增api-gateway.yaml配置集,配置組爲TEST_GROUP,配置內容如下:

zuul:
  routes:
    application1:
      stripPrefix: false
      path: /application1/**

將請求爲/application1/開頭的請求路由至application1服務,保留請求url中的/application1/

1572442388728

(4) api-gateway啓動

注意在啓動類上使用@EnableZuulProxy註解標識此工程爲Zuul網關,啓動類代碼如下:

@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class ApiGatewayBootstrap {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayBootstrap.class, args);
    }
}

Service1Bootstrap 啓動後,應用 api-gateway 將出現在 Nacos 服務列表中。

1572442564557

測試:

通過網關(api-gateway)請求Application1應用,Application1的業務實現又貫穿service1、service2,訪問http://127.0.0.1:56010/application1/service ,將得到如下結果:

1571828918606

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章