SpringCloud-Gateway組件使用


1.什么是服務網關

1.說明

  • 網關統一服務入口,可方便實現對平台眾多服務接口進行管控,對訪問服務的身份認證、防報文重放與防數據篡改、功能調用的業務鑒權、響應數據的脫敏、流量與並發控制,甚至基於API調用的計量或者計費等等。

  • 網關 = 路由轉發 + 過濾器
    路由轉發:接收一切外界請求,轉發到后端的微服務上去; 在服務網關中可以完成一系列的橫切功能,例如權限校驗、限流以及監控等,這些都可以通過過濾器完成

2.為什么需要網關

  • 1.網關可以實現服務的統一管理
  • 2.網關可以解決微服務中通用代碼的冗余問題(如權限控制,流量監控,限流等)

3.網關組件在微服務中架構

2.服務網關組件

1.zuul

Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application. As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security.

  1. 原文翻譯

    • https://github.com/Netflix/zuul/wiki
    • zul是從設備和網站到Netflix流媒體應用程序后端的所有請求的前門。作為一個邊緣服務應用程序,zul被構建為支持動態路由、監視、彈性和安全性。
  2. zuul版本說明

    • 目前zuul組件已經從1.0更新到2.0,但是作為springcloud官方不再推薦使用zuul2.0,但是依然支持zuul2.
  3. springcloud 官方集成zuul文檔

2.gateway

This project provides a library for building an API Gateway on top of Spring MVC. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.

  1. 原文翻譯

    • https://spring.io/projects/spring-cloud-gateway
    • 這個項目提供了一個在springmvc之上構建API網關的庫。springcloudgateway旨在提供一種簡單而有效的方法來路由到api,並為api提供橫切關注點,比如:安全性、監控/度量和彈性。
  2. 特性

    • 基於springboot2.x 和 spring webFlux 和 Reactor 構建 響應式異步非阻塞IO模型
    • 動態路由
    • 請求過濾

創建一個新的項目,根據之前寫的環境搭建方式

3.開發網關動態路由

  • 網關配置有兩種方式一種是快捷方式,一種是完全展開方式

1.創建項目引入網關依賴

<!--引入gateway網關依賴-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

完整的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 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.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.md</groupId>
    <artifactId>05-gateway8989</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>05-gateway8989</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR6</spring-cloud.version>
    </properties>

    <dependencies>
       <!--使用網關的時候web包需要移除掉-->
        <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>
            <scope>test</scope>
        </dependency>

        <!--引入gateway網關依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!--引入consul依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>

        <!-- 這個包是用做健康度監控的-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

    </dependencies>

    <!--全局管理springcloud版本,並不會引入具體依賴-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</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>

</project>

快捷方式配置路由

2.編寫網關配置

spring:
  application:
    name: gateway
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}
    gateway:
      routes:
        - id: user_route    # 指定路由的唯一標識
          uri: http://localhost:9999/  # 指定路由服務的地址
          predicates:  # 指定路由的規則
            - Path=/user/**

        - id: product_route
          uri: http://localhost:9998/
          predicates:
            - Path=/product/**

server:
  port: 8989

3.啟動gateway網關項目

  • 直接啟動報錯:

  • 在啟動日志中發現,gateway為了效率使用webflux進行異步非阻塞模型的實現,因此和原來的web包沖突,去掉原來的web即可

  • 再次啟動成功啟動

4.測試網關路由轉發

使用之前寫的寫的,可以看前面幾篇文章

java方式配置路由(了解)

環境還是和上面的一樣

@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("order_route", r -> r.path("/order/**")
                        .uri("http://localhost:9997/"))
                .build();
    }
}

4.查看網關路由規則列表

1.說明

  • gateway提供路由訪問規則列表的web界面,但是默認是關閉的,如果想要查看服務路由規則可以在配置文件中開啟
management:
  endpoints:
    web:
      exposure:
        include: "*"   #開啟所有web端點暴露

訪問路由管理列表地址

3.配置路由服務負載均衡

1.說明

  • 現有路由配置方式,都是基於服務地址寫死的路由轉發,能不能根據服務名稱進行路由轉發同時實現負載均衡的呢?

2.動態路由以及負載均衡轉發配置

spring:
  application:
    name: gateway
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}
    gateway:
      routes:
        - id: user_route    # 指定路由的唯一標識
#          uri: http://localhost:9999/  # 指定路由服務的地址

          # lb代表轉發后台服務使用負載均衡,users代表服務注冊中心上的服務名
          uri: lb://users
          predicates:  # 指定路由的規則
            - Path=/user/**

        - id: product_route
#          uri: http://localhost:9998/

          # lb代表負載均衡轉發路由,products代表服務注冊中心上的服務名
          uri: lb://products
          predicates:
            - Path=/product/**

      # 開啟根據服務名動態獲取路由地址
      discovery:
        locator:
          enabled: true

server:
  port: 8989

#開啟所有web端點暴露
management:
  endpoints:
    web:
      exposure:
        include: "*"

此時訪問就實現了負載均衡的效果

4.常用路由predicate(斷言,驗證)

1.Gateway支持多種方式的predicate

After、Before、Between用於商城活動的時候指定日期才能訪問

2.使用predicate

spring:
  application:
    name: gateway
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
        - id: user_route
          #uri: http://localhost:9999/
          uri: lb://users
          predicates:
            - Path=/user/**
            - After=2020-12-21T11:39:33.993+08:00[Asia/Shanghai]
            - Cookie=username,[A-Za-z0-9]+
            - Header=X-Request-Id, \d+

5.常用的Filter以及自定義filter

1.作用

  • 當我們有很多個服務時,比如下圖中的user-service、order-service、product-service等服務,客戶端請求各個服務的Api時,每個服務都需要做相同的事情,比如鑒權、限流、日志輸出等。


2.使用內置過濾器

spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: product_route
          #uri: http://localhost:9998/
          uri: lb://products     # lb: 使用負載均衡策略   products代表注冊中心的具體服務名
          predicates:
            - Path=/product/**
            #- After=2020-07-30T09:45:49.078+08:00[Asia/Shanghai]
          filters:
          # 為每個請求添加參數id=12
            - AddRequestParameter=id,12
          # 增加響應頭  
            - AddResponseHeader=username,chenyn

3.使用自定義filter

@Configuration
@Slf4j
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("進入自定義的filter");
        if(exchange.getRequest().getQueryParams().get("username")!=null){
            log.info("用戶身份信息合法,放行請求繼續執行!!!");
            return chain.filter(exchange);
        }
        log.info("非法用戶,拒絕訪問!!!");
       return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {  //filter 數字越小filter越先執行
        return -1;           //-1  最先執行
    }
}

自定義全局filter



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM