SpringCloud(H版)學習---服務網關


一、概述

  上一代zuul 1.x:https://github.com/Netflix/zuul/wiki

  關於zuul的鄙人之前博客:SpringCloud全家桶學習之路由網關----Zuul(六),不過看上圖就知道該用誰了,沒錯-----GateWay(其用到了一些新技術如Netty、Spring Web  Flux等)更值得我們學習。

二、Gateway

  官網地址:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

  Spring Cloud Gateway基於Web Flux框架實現,而Web Flux框架底層則使用了高性能的Reactor模式通信框架Netty。SpringCloud Gateway的目標是提供統一的路由方式且基於Filter鏈的方式提供了網關基本的功能,例如安全、監控/指標,限流等。

1、三大核心概念

(1)Route路由:路由是構建網關的基本模塊,它由ID、目標URI、一系列的斷言和過濾器組成,如果斷言為true則匹配該路由

(2)Predicate斷言:開發人員可以匹配Http請求中的所有內容(例如請求頭、請求參數)如果請求與斷言相匹配則進行路由(參考:Java8:java.util.function.Predicate)

(3)Filter過濾:指的是Spring框架中GatewayFilter的實例,使用過濾器,可以在請求被路由之前或者之后對請求進行修改

2、工作流程

  ①客戶端向SpringCloud Gateway發出請求,然后在GateWay Handler Mapping中找到與請求相匹配的路由,將其發送到Gateway Web Hander;

  ②Handler再通過指定的過濾器鏈來將請求發送到我們實際的服務執行業務邏輯,然后返回。過濾器之間用虛線分開是因為過濾器可能在發送代理請求之前(“pre”)或之后(“post”)執行業務邏輯

  ③Filter在“pre”類型的過濾器中可以做參數校驗、權限校驗、流量監控、日志輸出、協議轉換等;在“post”類型的過濾器中可以做響應內容、響應頭的修改、日志輸出、流量監控等有着非常重要的作用。

核心邏輯:路由轉發+執行過濾器鏈

三、Gateway工程搭建

1、網關路由配置

1、yml配置網關路由

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 開啟從注冊中心動態創建路由的功能,利用微服務名稱j進行路由
      routes:
        - id: payment_route # 路由的id,沒有規定規則但要求唯一,建議配合服務名
          #匹配后提供服務的路由地址
          uri: http://localhost:8001
          predicates:
            - Path=/payment/get/** # 斷言,路徑相匹配的進行路由
            #- After=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+ #請求頭要有X-Request-Id屬性,並且值為正數
            #- Host=**.atguigu.com
            #- Method=GET
            #- Query=username, \d+ # 要有參數名username並且值還要是正整數才能路由
          # 過濾
          #filters:
          #  - AddRequestHeader=X-Request-red, blue
        - id: payment_route2
          uri: http://localhost:8001
          predicates:
            Path=/payment/lb/** #斷言,路徑相匹配的進行路由

eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
application.yml

分析:

  ①添加網關前訪問:http://localhost:8001/payment/get/31

  ②添加網關后訪問:http://localhost:9527/payment/get/31

2、硬編碼方式注入RouteLocator Bean配置路由

  參考官網案例:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

  業務需求:通過9527網關訪問到外網的百度新聞網址

@Configuration
public class GatewayConfig {

    /**
     * 配置了一個id為route-name的路由規則
     * 當訪問localhost:9527/guonei的時候,將會轉發至https://news.baidu.com/guonei
     *
     * @param routeLocatorBuilder
     * @return
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        return routes.route("path_route_xd",
                r -> r.path("/guonei").uri("https://news.baidu.com/guonei")).build();
    }

    @Bean
    public RouteLocator customRouteLocator2(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        return routes.route("path_route_xd1",
                r -> r.path("/guoji").uri("https://news.baidu.com/guoji")).build();
    }
}
GatewayConfig

 分析:上述配置provider方提供均是寫死的,需要改造。

3、微服務名實現動態路由配置

  默認情況下,Gateway會根據注冊中心的服務列表,以注冊中心上微服務名為路徑創建動態路由進行轉發,從而實現動態路由的功能。將uri配置為微服務名,並負載均衡

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 開啟從注冊中心動態創建路由的功能,利用微服務名稱進行路由
      routes:
        - id: payment_route # 路由的id,沒有規定規則但要求唯一,建議配合服務名
          #匹配后提供服務的路由地址
#          uri: http://localhost:8001
          uri: lb://CLOUD-PAYMENT-SERVICE
          predicates:
            - Path=/payment/get/** # 斷言,路徑相匹配的進行路由
            #- After=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+ #請求頭要有X-Request-Id屬性,並且值為正數
            #- Host=**.atguigu.com
            #- Method=GET
            #- Query=username, \d+ # 要有參數名username並且值還要是正整數才能路由
          # 過濾
          #filters:
          #  - AddRequestHeader=X-Request-red, blue
        - id: payment_route2
          uri: lb://CLOUD-PAYMENT-SERVICE
#          uri: http://localhost:8001
          predicates:
            Path=/payment/lb/** #斷言,路徑相匹配的進行路由

eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
application.yml

2、常用Predicates

  官網:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories
 可以對路由進行更精細的控制,例如header、cookie等等。

3、自定義Filter

  官網:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gatewayfilter-factories

  Filter分類:Gateway Fliter(單一31種)、Global Filter(全局--10種)

  自定義過濾器類實現GlobalFilter,Orderd接口即可

@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("come in global filter: {}", new Date());

        ServerHttpRequest request = exchange.getRequest();
        String uname = request.getQueryParams().getFirst("uname");
        if (uname == null) {
            log.info("用戶名為null,非法用戶");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        // 放行
        return chain.filter(exchange);
    }

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

Github地址:https://github.com/Simple-Coder/cloud2020


免責聲明!

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



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