天天看點

SpringCloud服務網關GatewaySpringCloud GatewayGateway三大核心概念Gateway工作流程Gateway網關的使用通過Java代碼配置網關通過微服務名稱實作動态路由Predicates規則過濾器(Filter)

SpringCloud Gateway

SpringCloud Gateway是Spring Cloud的一個全新項目,基于Spring5.0 + Spring Boot2.0和Project Reactor等技術開發的網關,它的宗旨是在為微服務架構提供一種簡單有效的統一的API路由管理方式。

SpringCloud Gateway作為Spring Cloud生态系統中的網關,目标是替代Zuul,在Sptring Cloud2.0以上版本中,沒有對新版本的Zuul2.0以上最新高性能版本進行內建,仍然還是使用Zuul1.0非Reactor模式的老版本。而為了提升網關的性能,SpringCloud Gateway是基于WebFlux架構實作的,而WebFlux架構底層則使用了高性能的Reactor模式通信架構Netty。

Gateway三大核心概念

  • 路由:路由時候建構網關的基本子產品,它由ID,目标URI,一系列的斷言和過濾組成,如果斷言為true則比對該路由
  • 斷言:開發人員可以1比對HTTP請求的所有内容,如果請求與斷言比對則進行路由
  • 過濾:指的是Spring架構中GatewayFilter的執行個體,使用過濾器,可以在請求被路由前或者之後對請求進行修改

Gateway工作流程

SpringCloud服務網關GatewaySpringCloud GatewayGateway三大核心概念Gateway工作流程Gateway網關的使用通過Java代碼配置網關通過微服務名稱實作動态路由Predicates規則過濾器(Filter)

用戶端向Spring Cloud Gateway送出請求。然後再Gateway Handler Mapping 中找到與請求相比對的路由,将其發送到Gateway Web Handler。Handler再通過制定的過濾器鍊來将請求發送到我們實際的服務執行業務邏輯。

Gateway網關的使用

  1. SpringBoot項目添加maven依賴
    <!--   gateway   -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
               
  2. 配置檔案添加網關路由配置
    server:
      port: 9527
    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          routes:
           - id: payment_route            #路由id,自定義唯一值
             uri: http://localhost:8001   #真實提供服務的位址
             predicates:
              - Path=/payment/get/**       #斷言:路徑相比對的進行路由
           - id: payment_route2
             uri: http://locahost:8001
             predicates:
              - Path=/payment/delete/**
    
    #eureka client
    eureka:
      instance:
        hostname: cloud-gateway-service
      client:
        service-url:
          register-with-eureka: true
          fetch-registry: true
          defaultZone: http://eureka1.com:7001/eureka/
               
  3. 啟動類
    @SpringBootApplication
    @EnableEurekaClient
    public class GatewayApplication {
        public static void main(String[] args) {
            SpringApplication.run(GatewayApplication.class,args);
        }
    }
               
  4. 請求測試,通過網關通路實際接口
    SpringCloud服務網關GatewaySpringCloud GatewayGateway三大核心概念Gateway工作流程Gateway網關的使用通過Java代碼配置網關通過微服務名稱實作動态路由Predicates規則過濾器(Filter)

通過Java代碼配置網關

可以不用上面配置檔案的方法配置網關,直接在Spring中注入RouteLocator,通過Java代碼實作網關路由配置

@Configuration
public class GatewayConfig {

    /**
     * spring中注入bean  RouteLocator
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
        RouteLocatorBuilder.Builder routes = builder.routes();
        //路由配置
        routes.route("payment_route",r -> r.path("/payment/get/**").uri("http://localhost:8001")).build();
        routes.route("paymemt_route1", r -> r.path("/payment/delete/**").uri("http://localhost:8001")).build();
        return routes.build();
    }
}
           

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

Gateway注冊進服務注冊中心。配置檔案開啟動态建立路由,服務通路位址換成微服務名稱

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
       - id: payment_route
         uri: lb://cloud-payment-service   # 提供服務的路由位址 lb://{服務名稱}
         predicates:
          - Path=/payment/get/**
      discovery:
        locator:
          enabled: true  #開啟從注冊中心動态建立路由功能,利用微服務名稱進行路由

#eureka client
eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka1.com:7001/eureka/
           

Predicates規則

predicates:
 - Path=/payment/get/**  #服務位址
 - After=2021-03-22T20:38:31.461+08:00[Asia/Shanghai] #在這個時間之後才能通路
 - Before=2021-03-22T25:38:31.461+08:00[Asia/Shanghai] #在這個時間之前才能通路
 - Cookie=[cookiename],[正規表達式] #cookie裡對應的cookiename符合正規表達式才可以通路
 - Header=[headername],[正規表達式] #請求頭裡對應的name符合正則才可以通路
 - Method=GET #隻允許get方法請求
 - Query=[paramName],[正規表達式] #參數paramName的值必須符合正則才可以通路,比如 price,[1-9]\d+(.\d{1,2})?,參數price必須是大于0的金額才能通路
 - Host=**.baidu.com #符合的host才可以通路
           

過濾器(Filter)

路由過濾器可用于修改進入的HTTP請求和傳回HTTP響應(跟web.xml配置的過濾器一樣)。Spring Cloud Gateway内置了多種路由過濾器,他們都由GatewayFilter的工廠類來産生。

自定義過濾器

/**
 * 全局自定義過濾器
 * 繼承GlobalFilter,Ordered
 */
@Component
public class MyFilter implements GlobalFilter,Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //擷取參數
        String username = exchange.getRequest().getQueryParams().getFirst("username");
        if(username == null){
            System.out.println("======非法請求======");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
            //攔截請求直接傳回
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 加載過濾器的順序,越小優先級越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}