天天看點

springcloud gateway概念精講

點選上方藍色字型,選擇“标星公衆号”

優質文章,第一時間送達

一、定義

外部請求通過gateWay轉發到後端微服務,網關一般提供如下功能

  1. 統一接入,路由轉發
  2. 安全審查,校驗鑒權
  3. 熔斷降級,資料緩存
  4. 統一日志,全局監控

總的來說,gateway提供了一個入口來管控所有的微服務,基于這個特點可以靈活使用。

網關解決方案對比

nginx+lua 高性能反向代理伺服器,一般作為負載均衡入口

Zuul是第一代網關,spring

cloud是第二代網關,基于Netty\Reactor\WebFLux建構

  • 性能強勁,zuul1.6倍
  • 功能強大,内置轉發,監控,限流等功能

缺點

  • 不能再servlet容器下功能,不能使用war包

基礎說明

  1. spring cloud gateway基于springBoot2.x系列,webflux,reactor等技術,傳統的同步庫都是不能使用的
  2. gateway底層依賴netty,不接受servlet容器或者war包

二、核心術語

Route路由

基礎的轉發規則,包含下面幾部分,當predicate滿足時則代表比對

  • id
  • 目标url
  • predicate集合:滿足條件才轉發
  • filter集合:滿足條件則過濾(改變請求)

Predicate謂詞、斷言

java.util.funcation.Predicate實作路由比對條件,通過

ServletWebExchange

(封裝了HTTP請求和相應)作為入參,來對request的各種屬性(參考predicate的各種規則)做比對。

Filter過濾器

修改請求及響應

gateway已經為了我們準備了各種過濾器工廠,我們也可以通過自定義過濾器

三、簡單原理

springcloud gateway概念精講
  1. client發送請求給gateway,handlermapping判斷請求路徑是否比對路由配置
  2. 如果比對成功web handler會讀取路由配置過濾器,把請求交給過濾器處理
  3. 過濾器如圖是鍊式結構,分為pre和post處理

四、概念講解

Route Predcate Factories

符合Predicate的條件,就使用該路由的配置,否則就不管。

https://www.imooc.com/article/290804

配置形式

模糊比對和精确比對

路由到指定URL

spring:
  cloud:
    gateway:
      routes:
      - id: {唯一辨別}
        uri: http://www.itmuch.com

           

表示通路 GATEWAY_URL/** 會轉發到 http://www.itmuch.com/**

需要和predicate配合使用,滿足條件則轉發

spring:
  cloud:
    gateway:
      routes:
      - id: {唯一辨別}
        uri: http://www.itmuch.com/spring-cloud/spring-cloud-stream-pan-ta/

           

表示通路 GATEWAY_URL/spring-cloud/spring-cloud-stream-pan-ta/ 會轉發到 http://www.itmuch.com/spring-cloud/spring-cloud-stream-pan-ta/

路由轉發到微服務

路由到服務發現元件上的微服務

 routes:
        - id: user_route
          uri: lb://user-center
          predicates:
            - Path=/users/**

           

浏覽器通路 網關url時,

http://localhost:8040/users/1

會自動轉發到user-center服務的接口,等同于通路

http://localhost:9099/users/1

自定義predicate工廠

xxxxRoutePredicateFactory必須以這種形式結尾

      routes:
        - id: after_route
          uri: lb://user-center
          predicates:
            # 當且僅當請求時的時間After配置的時間時,才會轉發到使用者微服務
            # 目前配置不會進該路由配置,是以傳回404
            # 将時間改成 < now的時間,則通路localhost:8040/** -> user-center/**
            # eg. 通路http://localhost:8040/users/1 -> user-center/users/1
            - After=2010-01-20T17:42:47.789-07:00[America/Denver]
            - TimeBetween=00:00:00,12:44:13

           
@Data
public class TimeBetweenBean {
    private String  start;
    private String end;
}


           
@Component
public class TimeBetweenRoutePredicateFactory
        extends AbstractRoutePredicateFactory <TimeBetweenBean>{

    public TimeBetweenRoutePredicateFactory() {
        super(TimeBetweenBean.class);
    }

    /**
     * 謂詞工廠的核心方法,控制路由的判斷人條件
     * @param config
     * @return
     */
    @Override
    public Predicate<ServerWebExchange> apply(TimeBetweenBean config) {

        String start = config.getStart();
        String end = config.getEnd();
        return  serverWebExchange ->{
            LocalTime now = LocalTime.now();
            System.out.println(now.isAfter(LocalTime.parse(start)));
            return now.isAfter(LocalTime.parse(start)) && now.isBefore(LocalTime.parse(end));
        };
    }

    /**
     * 控制配置類和配置檔案映射關系,和配置檔案順序一緻
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {

        return Arrays.asList("start","end");
    }
}


           

動态路由-服務名稱轉發

面向服務的路由,支援整合EUREKA或者NACOS注冊中心,根據serviceId自動從注冊中心擷取服務位址并轉發請求。不需要給每個微服務都配置路由規則

      discovery:
        locator:
          enabled: true # 開啟從注冊中心動态建立路由

           

例子:

http://localhost:8001/payment/get/1?uname=123

http://localhost:9527/cloud-payment-service/payment/get/1?uname=123

五、Filter

生命周期

  • Pre:轉發請求之前
  • post:轉發請求之後

gateway自帶過濾器講解

1. RewritePath 請求位址重定向

按照正則比對上的路徑重寫為逗号後面的位址

pring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: https://example.org
        predicates:
        - Path=/red/**
        filters:
        - RewritePath=/red/?(?<segment>.*), /$\{segment}

           

注:效果是去掉/red

2. PrefixPath 添加字首

給請求路徑添加字首

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - PrefixPath=/mypath

           

3. StripPrefix 删除字首

删除請求的指定個數字首後添加到服務末尾

spring:
  cloud:
    gateway:
      routes:
      - id: nameRoot
        uri: https://nameservice
        predicates:
        - Path=/name/**
        filters:
        - StripPrefix=2

           

例如:請求路徑/name/blue/red,實際效果 nameservice/red

全局過濾器GlobalFilter

無需配置檔案作用在所有的路由,最終通過gatewayfilterAdapter包裝為過濾器

自定義過濾器工廠

  • 繼承AbstractGateWayFilterFactory
  • 繼承AbstractNameValueGatewayFilterFactory

    第一種方式的簡化方式

自定義網關過濾器

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


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
       log.info("**** com int mylogglbalfiltert{}",new Date());
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if(uname==null){
            log.info("非法使用者");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE); //傳回狀态碼
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}


           

注冊過濾器

@Configuration
public class GateWayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){

        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_route_kouryoushine",
                r->r.path("guonei").
                        uri("http://news.baidu.com/guonei")).build();

        return routes.build() ;
    }

}

           

全局過濾器

無需注冊操作,預設直接生效

核心API

  • exchange.getRequest().mutate().xxx 修改request
  • exchange.mutate.xxx 修改exchange
  • chain.filter(exchange) 傳遞給下一個過濾器
  • exchange.getResponse() 擷取響應

配置檔案

    filters:
            - AddRequestHeader=X-Request-Foo,Bar
            - PreLog=a,b

           
@Slf4j
@Component
public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        log.info("請求建立了{}{}",config.getName(),config.getValue());
        return (exchagne,chain)->{
            log.info("請求建立了{}{}",config.getName(),config.getValue());
            ServerHttpRequest request = exchagne.getRequest()
                    .mutate()
                    .build();
            ServerWebExchange exchange = exchagne.mutate()
                    .request(request)
                    .build();
            return chain.filter(exchange);
        };
    }
}

           

order越小有效執行

局部過濾器按照配置順序執行

如果想自行控制order,傳回OrderedGateFilter

全局監控

檢視全局過濾器

http://localhost:8040/actuator/gateway/globalfilters

  • routes展示路由清單

其他監控包括動态增加路由都可以百度

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結和本聲明。

本文連結:

https://blog.csdn.net/kouryoushine/article/details/117048823

springcloud gateway概念精講
  • 76套java從入門到精通實戰課程分享

  • 50份優秀Java求職者履歷

  • 新款SpringBoot線上教育平台開源了

  • 2020年全網最全BAT筆試面試題打包分享