天天看點

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

文章目錄

  • SpringCloud Alibaba
    • 一、 簡介
    • 二、 Nacos主要功能
    • 三、 Nacos-Helloworld案例開發
      • 1 案例分析
      • 2 SpringCloud Alibaba Nacos服務注冊和配置中心
        • 2.1 Nacos簡介
        • 2.2 下載下傳Nacos
        • 2.3 啟動Nacos
        • 2.4 通路Nacos
      • 3 基于Nacos建立服務提供者
        • 3.1 建立工程: nacos-provider-movie
        • 3.2 yml添加配置
        • 3.3 主程式添加注解:EnableDiscoveryClient
        • 3.4 多執行個體啟動,檢視Nacos控制台
      • 4 基于Nacos建立服務消費者
        • 4.1 建立工程: nacos-consumer-user
        • 4.2 yml添加配置
        • 4.3 主程式添加注解:EnableDiscoveryClient
        • 4.4 檢視Nacos控制台
      • 5 使用Feign實作服務調用
        • 5.1 在nacos-consumer-user項目中引入feign的依賴
        • 5.2 在nacos-consumer-user項目主程式類名上添加@EnableFeignClients注解
        • 5.3 在nacos-consumer-user項目中編寫要調用nacos-provider-movie項目Controller對應的FeignClient
        • 5.4 在nacos-consumer-user項目中使用FeignClient遠端調用完成業務
        • 5.5 浏覽器通路測試: http://localhost:9000/consumer/test
    • 四、 Nacos-配置中心
      • 1 nacos建立統一配置
        • 1.1 dataId 的完整格式如下:
        • 1.2 配置内容說明:
      • 2 從配置中心讀取配置
        • 2.1 nacos-provider-movie項目引入依賴
        • 2.2 在bootstrap.properties中配置nacos
        • 2.3 在需要加載nacos配置的Controller上添加注解@RefreshScope實作自動更新
        • 2.4 測試
      • 3 名稱空間切換環境
        • 3.1 建立名稱空間
        • 3.2 切換到配置清單:
        • 3.3 在服務提供方nacos-provider-movie中切換命名空間
        • 3.4 重新開機服務提供方服務,在浏覽器中通路測試:
      • 4 復原配置
        • 4.1檢視曆史版本
        • 4.2 復原到某個曆史版本
      • 5 加載多配置檔案
      • 6 配置的分組
    • 五、 Sentinel實作熔斷與限流
      • 1 Spring Alibaba Sentinel 簡介
      • 2 Sentinel與Hystrix的差別
      • 3 下載下傳安裝Sentinel
        • 3.1 Sentinel組成
        • 3.2 下載下傳
      • 4 運作
      • 5 通路sentinel控制台
      • 6 消費者服務整合Sentinel
        • 6.1 修改:cloudalibaba-sentinel-service8401
        • 1. YML
        • 2. 添加Nacos業務規則配置
        • 3. 啟動8401後重新整理sentinel發現業務規則有了
        • 4. 快速通路測試接口
        • 5. 停止8401再看sentinel
        • 6. 重新啟動8401再看sentinel
  • Zuul網關(課餘了解)
    • 10.1 建立Zuul工程
    • 10.2 通路測試
      • 1 初步通路
      • 2 使用指定位址代替微服務名稱
      • 3 讓使用者不能通過微服務名稱通路
      • 4 忽略所有微服務名稱
      • 5 給通路路徑添加統一字首
    • 10.3 過濾功能:ZuulFilter
      • 案例:使用zuul網關實作ip黑名單

SpringCloud Alibaba

一、 簡介

由于性能關系,Eureka停止更新,Hystrix和Ribbon進入維護模式,不再繼續更新。

2018.10.31,Spring Cloud Alibaba正式入駐了Spring Cloud官網孵化器,并在Maven中央庫釋出了第一個版本。Spring Cloud Alibaba 緻力于提供微服務開發的一站式解決方案。此項目包含開發分布式應用微服務的必需元件,友善開發者通過 Spring Cloud 程式設計模型輕松使用這些元件來開發分布式應用服務。依托 Spring Cloud Alibaba,您隻需要添加一些注解和少量配置,就可以将 Spring Cloud 應用接入阿裡微服務解決方案,通過阿裡中間件來迅速搭建分布式應用系統。

參考:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md

常見的注冊中心:

Eureka(原生,2.0遇到性能瓶頸,停止維護)

Zookeeper(支援,專業的獨立産品。例如:dubbo)

Consul(原生,GO語言開發)

Nacos

相對于 Spring Cloud Eureka 來說,Nacos 更強大。

Nacos = Spring Cloud Eureka + Spring Cloud Config

Nacos 可以與 Spring, Spring Boot, Spring Cloud 內建,并能代替 Spring Cloud Eureka, Spring Cloud Config。

通過 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 實作配置的動态變更。

通過 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 實作服務的注冊與發現。

nacos在阿裡巴巴内部有超過10萬的執行個體運作,已經過了類似雙十一等各種大型流量的考驗。

二、 Nacos主要功能

Nacos主要提供以下四大功能:

服務發現和服務健康監測

動态配置服務

動态DNS服務

服務及其中繼資料管理

面試題:微服務間遠端互動的過程?

先去注冊中心查詢服務的伺服器位址

調用方給對方發送http請求

三、 Nacos-Helloworld案例開發

1 案例分析

需求:電影查詢系統

使用者通路使用者服務可以查詢使用者資訊或者查詢使用者資訊+電影資訊

​ 電影服務可以查詢電影資訊

2 SpringCloud Alibaba Nacos服務注冊和配置中心

2.1 Nacos簡介

Nacos:Dynamic Naming and Configuration Service

一個更易于建構雲原生應用的動态服務發現,配置管理和服務管理中心

Nacos就是注冊中心+配置中心的組合

等價于

Nacos = Eureka+Config+Bus

2.2 下載下傳Nacos

下載下傳位址: https://github.com/alibaba/nacos/archive/1.1.4.tar.gz

下載下傳nacos-server-1.1.4.zip後解壓即可

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

2.3 啟動Nacos

1 Linux/Unix/Mac

啟動指令(standalone代表着單機模式運作,非叢集模式):

sh startup.sh -m standalone
           

2 Windows

啟動指令:

cmd startup.cmd
           

或者輕按兩下startup.cmd運作檔案。

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

2.4 通路Nacos

浏覽器通路:http://localhost:8848/nacos

會跳轉到登入頁面,賬号密碼預設都是nacos,端口号為8848

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

注冊中心已經準備完畢,我們再基于Nacos注冊中心建立服務提供者和消費者

3 基于Nacos建立服務提供者

3.1 建立工程: nacos-provider-movie

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

引入子產品 spring web

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

pom****檔案添加依賴,注意:nacos版本 0.2.x.RELEASE 對應的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 對應的是 Spring Boot 1.x 版本。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>0.2.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
<!-- SpringCloud的依賴 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
           

3.2 yml添加配置

server:
  port: 8000
spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
           

3.3 主程式添加注解:EnableDiscoveryClient

3.4 多執行個體啟動,檢視Nacos控制台

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

浏覽器通路:http://localhost:8488/nacos

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

4 基于Nacos建立服務消費者

4.1 建立工程: nacos-consumer-user

引入子產品和依賴參考服務提供者

4.2 yml添加配置

server.port=9000
spring.application.name=nacos-consumer-user
spring.cloud.nacos.discovery.server-addr=localhost:8848
           

4.3 主程式添加注解:EnableDiscoveryClient

4.4 檢視Nacos控制台

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

5 使用Feign實作服務調用

5.1 在nacos-consumer-user項目中引入feign的依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
           

5.2 在nacos-consumer-user項目主程式類名上添加@EnableFeignClients注解

5.3 在nacos-consumer-user項目中編寫要調用nacos-provider-movie項目Controller對應的FeignClient

5.4 在nacos-consumer-user項目中使用FeignClient遠端調用完成業務

5.5 浏覽器通路測試: http://localhost:9000/consumer/test

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

四、 Nacos-配置中心

在系統開發過程中,開發者通常會将一些需要變更的參數、變量等從代碼中分離出來獨立管理,以獨立的配置檔案的形式存在。目的是讓靜态的系統工件或者傳遞物(如 WAR,JAR 包等)更好地和實際的實體運作環境進行适配。配置管理一般包含在系統部署的過程中,由系統管理者或者運維人員完成。配置變更是調整系統運作時的行為的有效手段。

如果微服務架構中沒有使用統一配置中心時,所存在的問題:

配置檔案分散在各個項目裡,不友善維護

配置内容安全與權限

更新配置後,項目需要重新開機

nacos配置中心:系統配置的集中管理(編輯、存儲、分發)、動态更新不重新開機、復原配置(變更管理、曆史版本管理、變更審計)等所有與配置相關的活動。

案例:改造生産者中的動态配置項,由配置中心統一管理。

1 nacos建立統一配置

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)
SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

1.1 dataId 的完整格式如下:

​ $ {prefix}-$ {spring.profile.active}.${file-extension}

– prefix 預設為所屬工程配置spring.application.name 的值(即:nacos-provider),也可以通過配置項 spring.cloud.nacos.config.prefix來配置。

– spring.profile.active 即為目前環境對應的 profile,詳情可以參考 Spring Boot文檔。 注意:當 spring.profile.active 為空時,對應的連接配接符 - 也将不存在,dataId 的拼接格式變成 $ {prefix}.$ {file-extension}

– file-exetension 為配置内容的資料格式,可以通過配置項 spring.cloud.nacos.config.file-extension 來配置。目前隻支援 properties 和 yaml 類型。

​ 總結:配置所屬工程的spring.application.name的值 + “.” + properties/yml

1.2 配置内容說明:

​ 項目中易變的内容。例如:myName

目前案例中,nacos-provider-movie工程的spring.application.name= nacos-provider-movie,沒有配置spring.profiles.active。是以這裡的dataId填寫的是nacos-provider.properties

2 從配置中心讀取配置

2.1 nacos-provider-movie項目引入依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>0.2.1.RELEASE</version>
</dependency>
           

2.2 在bootstrap.properties中配置nacos

spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# 該配置影響統一配置中心中的dataId,之前已經配置過
spring.application.name=nacos-provider-movie
           

2.3 在需要加載nacos配置的Controller上添加注解@RefreshScope實作自動更新

@RefreshScope
@RestController
public class ProviderController {
    @Value("${myName}")
    private String name;
    @GetMapping("/hello")
    public String hello(){
        return "hello " + name;
    }
}
           

2.4 測試

修改配置中心的配置,服務提供者會自動重新整理修改的屬性的

屬性值。

3 名稱空間切換環境

在實際開發中,通常有多套不同的環境(預設隻有public),那麼這個時候可以根據指定的環境來建立不同的 namespce,例如,開發、測試和生産三個不同的環境,那麼使用一套 nacos 叢集可以分别建以下三個不同的 namespace。以此來實作多環境的隔離。

3.1 建立名稱空間

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

3.2 切換到配置清單:

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

可以發現有四個名稱空間:public(預設)以及我們自己添加的3個名稱空間(prod、dev、test),可以點選檢視每個名稱空間下的配置檔案,當然現在隻有public下有一個配置。

預設情況下,項目會到public下找 服務名.properties檔案。

接下來,在dev名稱空間中也添加一個nacos-provider-movie.properties配置。這時有兩種方式:

1 切換到dev名稱空間,添加一個新的配置檔案。缺點:每個環境都要重複配置類似的項目

2 直接通過clone方式添加配置,并修改即可。推薦

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)
SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)
SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

點選編輯:修改配置内容,以作區分

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

3.3 在服務提供方nacos-provider-movie中切換命名空間

修改bootstrap.properties添加如下配置

spring.cloud.nacos.config.namespace=dda09a20-c3f8-4a5d-a3c6-975bc4e273cc

namespace的值為:

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

3.4 重新開機服務提供方服務,在浏覽器中通路測試:

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

4 復原配置

復原配置隻需要兩步:

4.1檢視曆史版本

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

4.2 復原到某個曆史版本

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

5 加載多配置檔案

偶爾情況下需要加載多個配置檔案。假如現在dev名稱空間下有三個配置檔案:nacos-provider.properties、redis.properties、jdbc.properties。

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

nacos-provider-movie.properties預設加載,怎麼加載另外兩個配置檔案?

在bootstrap.properties檔案中添加如下配置:

spring.cloud.nacos.config.ext-config[0].data-id=redis.properties
# 開啟動态重新整理配置,否則配置檔案修改,工程無法感覺
spring.cloud.nacos.config.ext-config[0].refresh=true
spring.cloud.nacos.config.ext-config[1].data-id=jdbc.properties
spring.cloud.nacos.config.ext-config[1].refresh=true
           

修改ProviderController讀取redis.properties和jdbc.properties配置檔案中的參數:

@RefreshScope
@RestController
public class ProviderController {
    @Value("${myName}")
    private String name;
    @Value("${jdbc.url}")
    private String url;
    @Value("${redis.host}")
    private String host;
    @GetMapping("/hello")
    public String hello(){
        return "hello " + name+", redis:"+ host+", jdbc: "+url ;
    }
}
           

測試效果:

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

問題:

修改一下配置中心中redis.properties中的配置,不重新開機服務。能否加載配置資訊

删掉spring.cloud.nacos.config.ext-config[0].refresh=true,再修改redis.properties中的配置試試

6 配置的分組

在實際開發中,除了不同的環境外。不同的微服務或者業務功能,可能有不同的redis及mysql資料庫。區分不同的環境我們使用名稱空間(namespace),區分不同的微服務或功能,使用分組(group)。

當然,你也可以反過來使用,名稱空間和分組隻是為了更好的區配置設定置,提供的兩個次元而已。

新增一個redis.properties,所屬分組為provider:

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

現在開發環境中有兩個redis.propertis配置檔案,一個是預設分組(DEFAULT_GROUP),一個是provider組,預設情況下從DEFAULT_GROUP分組中讀取redis.properties,如果要切換到provider分組下的redis.properties,需要添加如下配置:

# 指定分組
spring.cloud.nacos.config.ext-config[0].group=provider
           

缺點:

将來每個分組下會有太多的配置檔案,不利于維護。

最佳實踐:

命名空間區分業務功能,分組區分環境。

五、 Sentinel實作熔斷與限流

1 Spring Alibaba Sentinel 簡介

官網:https://github.com/alibaba/Sentinel/wiki/介紹

随着微服務的流行,服務和服務之間的穩定性變得越來越重要。在大規模微服務架構的場景下,避免服務出現雪崩,要減少停機時間,要盡可能的提高服務可用性。限流和降級是一個非常重要的手段,具體實施方法可以歸納為八字箴言,分别是限流,降級,熔斷和隔離。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個次元保護服務的穩定性。

Sentinel 具有以下特征:

  • 豐富的應用場景:Sentinel 承接了阿裡巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、消息削峰填谷、叢集流量控制、實時熔斷下遊不可用應用等。
  • 完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制台中看到接入應用的單台機器秒級資料,甚至 500 台以下規模的叢集的彙總運作情況。
  • 廣泛的開源生态:Sentinel 提供開箱即用的與其它開源架構/庫的整合子產品,例如與 Spring Cloud、Dubbo、gRPC 的整合。您隻需要引入相應的依賴并進行簡單的配置即可快速地接入 Sentinel。
  • 完善的 SPI 擴充點:Sentinel 提供簡單易用、完善的 SPI 擴充接口。您可以通過實作擴充接口來快速地定制邏輯。例如定制規則管理、适配動态資料源等。

Sentinel 的主要特性:

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

Sentinel 目前已經針對 Servlet、Dubbo、Spring Boot/Spring Cloud、gRPC 等進行了适配,使用者隻需引入相應依賴并進行簡單配置即可非常友善地享受 Sentinel 的高可用流量防護能力。

2 Sentinel與Hystrix的差別

詳情參考:https://yq.aliyun.com/articles/633786/

2.1 Hystrix常用的線程池隔離會造成線程上下切換的overhead比較大;

2.2 Hystrix使用的信号量隔離對某個資源調用的并發數進行控制,效果不錯,但是無法對慢調用進行自動降級;

2.3 Sentinel通過并發線程數的流量控制提供信号量隔離的功能;

2.4 Sentinel支援的熔斷降級次元更多,可對多種名額進行流控、熔斷,且提供了實時監控和控制台,功能更為強大。

3 下載下傳安裝Sentinel

3.1 Sentinel組成

Sentinel 分為兩個部分:

1 核心庫(Java 用戶端)不依賴任何架構/庫,能夠運作于所有 Java 運作時環境,同時對 Dubbo / Spring Cloud 等架構也有較好的支援。

2 控制台(Dashboard)基于 Spring Boot 開發,打包後可以直接運作,不需要額外的 Tomcat 等應用容器。

3.2 下載下傳

位址:https://github.com/alibaba/Sentinel/releases/tag/1.7.2

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

4 運作

java -jar sentinel-dashboard-1.7.2.jar

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

5 通路sentinel控制台

http://localhost:8080,登入賬号密碼都是sentinel

6 消費者服務整合Sentinel

6.1 修改:cloudalibaba-sentinel-service8401

POM添加nacos依賴

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
           

1. YML

server:
  port: 8401
 
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服務注冊中心位址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard位址
        port: 8719
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
 
management:
  endpoints:
    web:
      exposure:
        include: '*'
 
feign:
  sentinel:
    enabled: true # 激活Sentinel對Feign的支援

           

2. 添加Nacos業務規則配置

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

· 内容解析

[
    {
         "resource": "/retaLimit/byUrl",
         "limitApp": "default",
         "grade":   1,
         "count":   1,
         "strategy": 0,
         "controlBehavior": 0,
         "clusterMode": false    
    }
]
           
SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

3. 啟動8401後重新整理sentinel發現業務規則有了

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

4. 快速通路測試接口

http://localhost:8401/rateLimit/byUrl

預設

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

5. 停止8401再看sentinel

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

6. 重新啟動8401再看sentinel

紮一看還是沒有,稍等一會兒

多次調用

http://localhost:8401/rateLimit/byUrl

重新配置出現了,持久化驗證通過

Zuul網關(課餘了解)

不同的微服務一般有不同的網絡位址,而外部的用戶端可能需要調用多個服務的接口才能完成一個業務需求。比如一個電影購票的手機APP,可能會調用電影分類微服務,使用者微服務,支付微服務等。如果用戶端直接和微服務進行通信,會存在以下問題:

Ø 用戶端會多次請求不同微服務,增加用戶端的複雜性

Ø 存在跨域請求,在一定場景下處理相對複雜

Ø 認證複雜,每一個服務都需要獨立認證

Ø 難以重構,随着項目的疊代,可能需要重新劃分微服務,如果用戶端直接和微服務通信,那麼重構會難以實施

Ø 某些微服務可能使用了其他協定,直接通路有一定困難

Zuul包含了對請求的路由和過濾兩個最主要的功能:

其中路由功能負責将外部請求轉發到具體的微服務執行個體上,是實作外部通路統一入口的基礎而過濾器功能則負責對請求的處理過程進行幹預,是實作請求校驗、服務聚合等功能的基礎。

Zuul和Eureka進行整合,将Zuul自身注冊為Eureka服務治理下的應用,同時從Eureka中獲得其他微服務的資訊,也即以後的通路微服務都是通過Zuul跳轉後獲得。

總體來說,Zuul提供了代理、路由和過濾的功能。

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

10.1 建立Zuul工程

Springboot項目:cloud-zuul , 并引入Eureka client、config、zuul依賴

SpringCloud AlibabaSpringCloud AlibabaZuul網關(課餘了解)

建立後依賴如下:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
           

配置applicaton.yml

server:
  port: 10000
spring:
  application:
    name: cloud-zuul
eureka:
  client:
    serviceUrl:
      defaultZone: http://192.168.200.1:8761/eureka/
           

主程式添加注解啟用zuul代理功能:@EnableZuulProxy

啟動cloud-zuul 項目

10.2 通路測試

1 初步通路

http://192.168.200.1:10000/cloud-provider-movie/movie

- http:// 192.168.200.1:10000/ :zuul網關項目位址端口号

- cloud-provider-movie/movie : 需要通路的目标服務的服務名+路徑

此時:通過Zuul可以通路,也可以不經過Zuul直接通路目标微服務。

http://192.168.200.1:8002/movie

2 使用指定位址代替微服務名稱

zuul:
  routes:
    helloworld:       # 自定義路由規則的名稱,在底層的資料結構中是Map的鍵
      serviceId: cloud-provider-movie   #目标微服務名稱,ZuulRoute類型的一個屬性
      path: /zuul-movie/**      # 用來代替目标微服務名稱的路徑,ZuulRoute類型的一個屬性
      # /**表示比對多層路徑,如果沒有加/**則不能比對後續的多層路徑了

           

效果:使用微服務自己的位址、微服務名稱和新配置的位址都可以通路

http://192.168.200.1:10000/cloud-provider-movie/movie

http://192.168.200.1:8002/movie

http://192.168.200.1:10000/zuul-movie/movie

3 讓使用者不能通過微服務名稱通路

zuul:
  ignored-services:         # 忽略指定微服務名稱,讓使用者不能通過微服務名稱通路
  - cloud-provider-movie
           

效果:微服務名稱不能通路,隻有新配置的位址可以通路

通路失敗:http://192.168.200.1:10000/cloud-provider-movie/movie

通路成功:http://192.168.200.1:10000/zuul-movie/movie

​ http://192.168.200.1:8002/movie

4 忽略所有微服務名稱

zuul:
  ignored-services: '*'     # 忽略所有微服務名稱
           

5 給通路路徑添加統一字首

zuul:
  prefix: /atguigu    # 給通路路徑添加統一字首
           

http://192.168.200.1:10000/atguigu/zuul-movie/movie

10.3 過濾功能:ZuulFilter

@Component
public class MyZuulFilter extends ZuulFilter {
    //判斷是否需要過濾本次請求
    @Override
    public boolean shouldFilter() {
        // 1.擷取目前RequestContext對象
        RequestContext context = RequestContext.getCurrentContext();
        // 2.擷取目前請求對象
        HttpServletRequest request = context.getRequest();
        // 3.擷取目前請求要通路的目标位址
        String servletPath = request.getServletPath();
        // 4.列印
        System.err.println("servletPath="+servletPath);
        // 5.目前方法傳回值
        // true:表示應該過濾,下面繼續執行run()方法
        // false:表示不過濾,直接放行
        return true;
    }
    //需要過濾請求的過濾邏輯
    @Override
    public Object run() throws ZuulException {
        System.err.println("run() ...");
        // 官方文檔:目前版本會忽略這個傳回值,傳回null即可
        return null;
    }
    // 傳回目前過濾器類型:過濾時機
    @Override
    public String filterType() {
        /*
        Zuul 中的過濾器總共有 4 種類型,且每種類型都有對應的使用場景。
	     “pre” 預過濾器 - 在路由分發一個請求之前調用。
	     “post” 後過濾器 - 在路由分發一個請求後調用。
	     “route” 路由過濾器 - 用于路由請求分發。
	     “error” 錯誤過濾器 - 在處理請求時發生錯誤時調用
        */
       return "pre";
    }
    // 過濾器執行順序
    @Override
    public int filterOrder() {
        return 0;
    }
}

           

案例:使用zuul網關實作ip黑名單

private List<String> blackIpList = Arrays.asList("127.0.0.1","192.168.200.1");
@Override
public Object run() {
    RequestContext ctx = RequestContext.getCurrentContext();
    String ip = ctx.getRequest().getRemoteHost();
    System.out.println("ip = " + ip);
    // 判斷是不是黑名單ip通路
    if (!StringUtils.isEmpty(ip) && blackIpList.contains(ip)) {
        ctx.setSendZuulResponse(false);
        ctx.setResponseBody("{\"code\":10001 , \"data\":\"請求被拒絕\"}");
        ctx.getResponse().setContentType("application/json; charset=utf-8");
        return null;
    }
    return null;
}