天天看點

Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

Gateway服務網關

  • Gateway服務網關概述
  • Gateway核心概念
  • Gateway執行個體與配置
  • 通過微服務名實作動态路由
    • 路由斷言工廠(Route Predicate Factories)
      • 一、After Route Predicate
      • 二、Before Route Predicate
      • 三、Between Route Predicate
      • 四、Cookie Route Predicate
      • 五、Header Route Predicate
      • 六、Host Route Predicate
      • 七、Method Route Predicate
      • 八、Path Route Predicate
      • 九、Query Route Predicate
      • 十、RemoteAddress Route Predicate
      • 十一、Weight Route Predicate
    • 網關過濾器工廠(GatewayFilter Factories)
      • 官網網關過濾器
      • 自定義網關過濾器
    • Gateway實作服務降級、熔斷、限流

Gateway服務網關概述

1、

SpringCloud Gateway

是 SpringCloud 的一個全新項目,基于

Spring 5.0 + Springboot 2.0 和 Project Reactor

等技術開發的服務網關,

它旨在為微服務架構提供一種簡單有效的統一的 API 路由管理方式。

SpringCloud Gateway 作為 SpringCloud 生态系統中的網關,目标是替代Zuul,在SpringCloud 2.0以上版本中,沒有對新版本的Zuul 2.0以上最新高性能版本進行內建,仍然還是使用的Zuul 1.x非Reactor模式的老版本。而為了提升網關的性能,SpringCloud Gateway 是基于

WebFlux

實作的,而WebFlux架構底層則使用了高性能的Reactor模式通信架構Netty。

作用

:Spring Cloud Gateway的目标提供統一的路由方式且基于Filter鍊的方式提供了網關基本的功能,例如:安全、監控/名額,和限流。(

反向代理、鑒權、流量控制、熔斷、日志監控.......

Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

2、為什麼要選擇Gateway?

Gateway:

(1)Gateway 是基于

異步非阻塞模型

進行開發的,性能強大。

(2)基于Spring 5.0、Project Reactor 和 SpringBoot 2.0 建構。

(3)動态路由:能夠比對任何請求屬性;

(4)可以對路由指定 Predicate(斷言)和 Filter(過濾器)。

(5)內建 Hystrix 的斷路器功能。

(6)內建SpringCloud的服務發現功能。

(7)易于編寫的 Predicate(斷言)和 Filter(過濾器)。

(8)請求限流功能。

(9)支援路徑重寫。

Zuul:

(1)Zuul 1.x 是一個

基于阻塞 I/O

的API網關

(2)

Zuul 1.x 是基于Servlet2.5 使用阻塞架構

,它

不支援在任何長連接配接

(如:WebSocket),Zuul的設計模式和Nginx較像,每次 I/O 操作都是從工作線程中選擇一個執行,請求線程被阻塞到工作線程完成,但是差别是Nginx是用C++實作。

Zuul用Java實作,而JVM本省會有第一次加載較慢的情況,使得Zuul的性能相對較差

(3)Zuul 2.x 理念更先進,想基于Netty 非阻塞和支援長連接配接,但SpringCloud目前還沒有整合。Zuul 2.x 的性能較Zuul 1.x 有較大提升。在性能方面,根據官方提供的基準測試,SpringCloud Gateway 的 RPS(每秒請求數)是 Zuul 的1.6倍。

(4)SpringCloud Gateway 建立在Spring 5.0、Project Reactor 和 SpringBoot 2.0 之上,使用非阻塞API。

(5)SpringCloud Gateway還支援WebSocket,并且與spring緊密繼承擁有更好的開發體驗。

Gateway核心概念

一、總體概念圖示:

1、

路由(Route):

路由是建構網關的基本子產品,它由ID、目标URI,一系列的斷言和過濾器組成,如果斷言為true,則比對該路由。

2、

斷言(predicate):

參考Java8的java.util.function.Predicate。

開發人員可以比對HTTP請求中的所有内容(如:請求頭、請求參數),如果請求與斷言相比對則進行路由

3、

過濾器(Filter):

指的是Spring架構中 GatewayFilter的執行個體,使用過濾器,可以在請求之前或者之後對請求進行修改。
Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由
web請求,通過與Predicate相比對,定位到真正的服務節點,并在這個轉發過程前後,進行一些精細化控制。Predicate就是請求的比對條件。而FIlter,就可以了解為一個無所不能的攔截器。有了這兩個元素,再加上目标URI,就可以實作一個具體的路由

二、Gateway工作流程圖

Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由
用戶端向 Spring Cloud Gateway 送出請求。如果網關處理程式映射确定請求與路由比對,則将其發送到網關 Web 處理程式。此處理程式通過特定于請求的過濾器鍊運作請求。過濾器被虛線分隔的原因是過濾器可以在發送代理請求之前和之後運作邏輯。執行所有

pre

過濾器邏輯。然後進行代理請求。發出代理請求後,将運作

post

過濾器邏輯。

Filter在

pre

類型的過濾器可以做

參數校驗、權限校驗、流量監控、日志輸出、協定轉換等。

post

類型的過濾器中可以做

相應内容、響應頭的修改、日志輸出、流量監控

等非常重要的作用。

Gateway執行個體與配置

官網配置:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html

一、方式一:yml 配置檔案配置

1、建立module:cloud-gateway-gateway9527

2、引入 pom 依賴

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

3、yml 配置檔案

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
      #路由的ID,沒有固定的配置規則,但要求唯一,建議配合服務名配置
      - id: payment_route1 
        #比對後提供服務的路由位址
        uri: http://localhost:8001
        predicates:
        #斷言,路徑相比對的進行路由
        - Path=/payment/get/**

      - id: payment_route2
        uri: http://localhost:8001
        predicates:
        - Path=/payment/lb/**
            
#注冊中心配置
eureka:
  client:
    #表示收将自己注冊到EurekaServer,預設為true
    register-with-eureka: true
    #是否從EurekaServer抓取已有的注冊資訊,預設為true,單節點無所謂,叢集必須設定為true才能配合ribbon使用負載均衡
    fetchRegistry: true
    service-url:
      #      defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    hostname: cloud-gateway-service
    instance-id: cloud-gateway-service9527
    prefer-ip-address: true   #通路路徑可以顯示IP位址
           

4、主啟動類

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

5、測試

測試位址:

http://localhost:8001/payment/get/1

http://localhost:9527/payment/get/1

測試發現兩個位址的通路結果一緻。

一、方式二:RouteLocator(路由定位)配置

@Configuration
public class GatewayConfig {

    /*路由國内新聞*/
    @Bean
    public RouteLocator customRouteRule(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_route_atguigu",
                route -> route.path("/guonei")
                        .uri("https://news.baidu.com/")).build();
        return routes.build();
    }
}
           

通過微服務名實作動态路由

預設情況下

:Gateway 會根據注冊中心的服務清單,以注冊中心上微服務名為路徑建立動态路由進行轉發,進而實作動态路由的功能。

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #開啟從注冊中心動态建立路由的功能,通過微服務名進行路由
      routes:
      #路由的ID,沒有固定的配置規則,但要求唯一,建議配合服務名配置
      - id: payment_route1
        #uri: http://localhost:8001  #比對後提供服務的路由位址
        uri: lb://cloud-payment-service #比對後提供服務的路由位址
        predicates:
        #斷言,路徑相比對的進行路由
        - Path=/payment/get/**

      - id: payment_route2
        #uri: http://localhost:8001
        uri: lb://cloud-payment-service #比對後提供服務的路由位址
        predicates:
        - Path=/payment/lb/**
        - After=2021-09-29T11:42:42.915+08:00[Asia/Shanghai]


eureka:
  client:
    #表示收将自己注冊到EurekaServer,預設為true
    register-with-eureka: true
    #是否從EurekaServer抓取已有的注冊資訊,預設為true,單節點無所謂,叢集必須設定為true才能配合ribbon使用負載均衡
    fetchRegistry: true
    service-url:
      #defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    hostname: cloud-gateway-service
    instance-id: cloud-gateway-service9527
    prefer-ip-address: true   #通路路徑可以顯示IP位址

           

需要注意的是:uri的協定為

lb

,表示啟用

Gateway的負載均衡功能

lb://micro-service-name

是 SpringCloud Gateway 在微服務中自動為我們建立的負載均衡 uri。

路由斷言工廠(Route Predicate Factories)

隻有滿足斷言的比對規則才能通過網關正常通路路由位址。

官網位址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

一、After Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]
           

表示在

指定時間之後

可以對該路由位址進行通路,否則通路

404 Not Found

,擷取改時間格式可通過如下方式擷取:

ZonedDateTime zonedDateTime = ZonedDateTime.now(); System.out.println(zonedDateTime);

zonedDateTime

就是我們需要配置的時間格式。

二、Before Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
           

表示在

指定時間之前

可以對該路由位址進行通路,否則通路

404 Not Found

,擷取時間格式同上。

三、Between Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
           

表示在

指定的時間區間内

可以對改路由位址正常通路,否則通路

404 Not Found

,擷取時間格式同上。

四、Cookie Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=name,test
           

postman測試:

Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

表示此路由比對具有名為

name

的 cookie 的請求,該 cookie 的值與

test

正規表達式

比對時,才能夠對改路由位址進行通路。否則通路 否則通路

404 Not Found

五、Header Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=token,123
           

postman測試:

Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

表示請求頭中包含字段名(任意字段)

token

,并且值與

123

正規表達式比對的請求,才能夠對該路由位址進行通路。否則通路

404 Not Found

六、Host Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.gateway.com,**.springcloudgateway.com
           

postman測試:

Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

表示請求頭中包含字段名

Host

,并且值與

123

正規表達式比對的請求,才能夠對該路由位址進行通路。否則通路

404 Not Found

七、Method Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST
           
Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

表示該請求方法必須是與指定的斷言中的Method比對,才能對該路由位址進行通路,否則通路

404 Not Found

八、Path Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}
           
Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

表示該請求的位址與指定斷言Path比對,才能對該路由位址進行通路,否則通路

404 Not Found

九、Query Route Predicate

1、隻要包含該查詢參數就可以比對成功

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=green
           
Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

2、包含查詢參數和值,其中值可以使用正規表達式比對,隻有key和value都比對上才能對該路由位址正常通路。

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=red, gree.
           
Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

十、RemoteAddress Route Predicate

1、如果請求的用戶端的ip位址是192.168.1.1到192.168.1.24的範圍。則路由會被轉發到 https://example.org。

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24
           

2、

暫未解決

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #開啟從注冊中心動态建立路由的功能,通過微服務名進行路由
      routes:
      - id: payment_route2
        uri: lb://cloud-payment-service #比對後提供服務的路由位址
        predicates:
        - Path=/payment/lb/**
        - RemoteAddr=192.168.0.1/24
           

十一、Weight Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2
           

表示該路由會将約 80% 的流量轉發到 weighthigh.org,約 20% 的流量轉發到 weightlow.org。

網關過濾器工廠(GatewayFilter Factories)

官網網關過濾器

官網配置:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

1、生命周期:

pre

post

2、種類:

31種

。見逛網配置。

自定義網關過濾器

1、Filter配置類(例:全局網關過濾器)

package com.atguigu.springcloud.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;

/**
 * @author 李宏偉
 * @version 1.0
 * @ClassName GlobalLogGatewayFilter
 * @Description
 * @date 2021年10月14日 10:14
 */
@Component
@Slf4j
public class GlobalLogGatewayFilter implements GlobalFilter, Ordered {

    /**
     * 全局日志網關過濾器:
     *  ServerWebExchange:表示Web請求服務,可擷取請求HttpServletRequest、響應HttpServletResponse等
     *  chain:表示網關過濾連
     *
     * @return
     * @params
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        log.info("***********Come in GlobalLogGatewayFilter:" + new Date());

        ServerHttpRequest request = exchange.getRequest();
        String name = request.getQueryParams().getFirst("name");
        if (name == null) {

            log.info("***********使用者名不能為空,非法使用者");

            //驗證失敗,設定請求失敗狀态
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            //最後終止向下一個過濾器方法提供委托,并傳回響應
            return exchange.getResponse().setComplete();
        }
        // 放行,并将委托給過濾鍊中的下一個過濾器
        return chain.filter(exchange);
    }

    /**
     * 可以在全局網關過濾器配置類中加入 @Order 注解代替實作Ordered接口
     * 加載過濾器的優先級,數值越小,加載優先級越高;反之越小
     *
     * @return
     * @params
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
           

2、測試:請求通路:

http://localhost:9527/payment/lb?name=123

能夠

正常傳回

,通路:

http://localhost:9527/payment/lb?age=123

是傳回如下狀态:

Gateway服務網關Gateway服務網關概述Gateway核心概念Gateway執行個體與配置通過微服務名實作動态路由

Gateway實作服務降級、熔斷、限流

參考文章:https://blog.csdn.net/zhuyu19911016520/article/details/86499528

繼續閱讀