My latest and most complete articles are in the pumpkin slow say www.pkslow.com, welcome to tea!

1 introduction

As the name implies, Spring Cloud Gateway is a Gateway component for microservices scenarios that is based on Spring WebFlux, Reactive. In principle, it should perform better than Zuul.

How it works is shown below:

In simple terms, a series of filters are used to process the requests matching the Predicates of a particular rule. So the main thing is to do two things:

(1) Predicates determines which requests can be processed by Predicates.

(2) How to process is determined by the Filters.

2 Route conditions are judged Predicates

2.1 Time match After

Indicates the time after which the conditional matching route is considered:

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After = 2020-01-20 T17:42:47. 789-07:00 [America/Denver]
Copy the code

2.2 Time match Before

Indicates the time before the route is matched:

spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before = 2017-01-20 T17:42:47. 789 - from America/Denver
Copy the code

2.3 Time range Matches Between

Indicates the time segment in which routes are matched:

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between = 2017-01-20 T17:42:47. 789 - from America/Denver, The 2017-01-21 T17:42:47. 789-07:00[America/Denver]
Copy the code

2.4 the Cookie matching

Indicates that routes are matched by judging the key value of cookies, where the value supports regular expression:

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p
Copy the code

2.5 Request Headers match Headers

Indicates matching a route by determining the Header of an Http request:

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+
Copy the code

2.6 The Host name matches Host

Match routes by determining Hostname:

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org
Copy the code

2.7 Request Method matches Method

Represents matching routes by determining the request method:

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST
Copy the code

2.8 Request Path Matching Path

Indicates that a route is matched by determining the request path.

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}
Copy the code

2.9 Request Parameters Match Query

Indicates matching routes by determining request parameters:

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=red, gree.
Copy the code

2.10 Matching RemoteAddr for IP Address

Indicates that routes are matched by judging IP addresses:

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

2.11 Weight Matches Weight

To match routes with weights:

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
Copy the code

3 Powerful GatewayFilter

Spring provides a number of powerful Gatewayfilters for processing requests.

3.1 Adding a Request Header

Add a Header to the request:

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - AddRequestHeader=X-Request-Red, Blue-{segment}
Copy the code

3.2 Adding request Parameters

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddRequestParameter=foo, bar-{segment}
Copy the code

3.3 Adding a Return Header

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddResponseHeader=foo, bar-{segment}
Copy the code

3.4 Deleting A Header repeatedly Returned

spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: https://example.org
        filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
Copy the code

3.5 Circuit Breaker Hystrix

Simple configuration:

spring:
  cloud:
    gateway:
      routes:
      - id: hystrix_route
        uri: https://example.org
        filters:
        - Hystrix=myCommandName
Copy the code

Complex configuration:

spring:
  cloud:
    gateway:
      routes:
      - id: hystrix_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingserviceendpoint
        filters:
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/incaseoffailureusethis
        - RewritePath=/consumingserviceendpoint, /backingserviceendpoint
Copy the code

3.6 CircuitBreaker

Simple configuration:

spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: https://example.org
        filters:
        - CircuitBreaker=myCircuitBreaker
Copy the code

Complex configuration:

spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis
        - RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint
Copy the code

3. 7 Request header name change

spring:
  cloud:
    gateway:
      routes:
      - id: map_request_header_route
        uri: https://example.org
        filters:
        - MapRequestHeader=Blue, X-Request-Red
Copy the code

3.8 Adding a Path Prefix

This is distinguished from the matching path, which is preceded by a prefix:

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

Request /hello becomes /mypath/hello.

3.9 the redirection

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - RedirectTo=302, https://acme.org
Copy the code

3.10 Deleting the Request Header

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: https://example.org
        filters:
        - RemoveRequestHeader=X-Request-Foo
Copy the code

3.11 Delete return header

spring:
  cloud:
    gateway:
      routes:
      - id: removeresponseheader_route
        uri: https://example.org
        filters:
        - RemoveResponseHeader=X-Response-Foo
Copy the code

3.12 Deleting Request Parameters

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestparameter_route
        uri: https://example.org
        filters:
        - RemoveRequestParameter=red
Copy the code

3.13 Rewriting a Path

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

3.14 Setting a Path

spring:
  cloud:
    gateway:
      routes:
      - id: setpath_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - SetPath=/{segment}
Copy the code

3.15 Setting the Request Header

spring:
  cloud:
    gateway:
      routes:
      - id: setrequestheader_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - SetRequestHeader=foo, bar-{segment}
Copy the code

3.16 Setting return headers

spring:
  cloud:
    gateway:
      routes:
      - id: setresponseheader_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - SetResponseHeader=foo, bar-{segment}
Copy the code

3.17 Setting the Return status Code

spring:
  cloud:
    gateway:
      routes:
      - id: setstatusstring_route
        uri: https://example.org
        filters:
        - SetStatus=BAD_REQUEST
      - id: setstatusint_route
        uri: https://example.org
        filters:
        - SetStatus=401
Copy the code

3.18 Removing the path prefix

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

/name/blue/red = nameservice /red = nameservice /red

3.19 try againRetry GatewayFilter

Surprisingly, there is a powerful retry feature:

spring:
  cloud:
    gateway:
      routes:
      - id: retry_test
        uri: http://localhost:8080/flakey
        predicates:
        - Host=*.retry.com
        filters:
        - name: Retry
          args:
            retries: 3
            statuses: BAD_GATEWAY
            methods: GET,POST
            backoff:
              firstBackoff: 10ms
              maxBackoff: 50ms
              factor: 2
              basedOnPreviousValue: false
Copy the code

3.20 Request Size Limit

spring:
  cloud:
    gateway:
      routes:
      - id: request_size_route
        uri: http://localhost:8080/upload
        predicates:
        - Path=/upload
        filters:
        - name: RequestSize
          args:
            maxSize: 5000000
Copy the code

3.21 the default Filter

If you want this to work for all routes, you can add the default Filter:

spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - PrefixPath=/httpbin
Copy the code

4 Global Filters

The GlobalFilter interface is the same as the GatewayFilter interface, but it is used for all routes. When the request comes in, the Filter Chain consists of all the GlobalFilters and matched GatewayFilters in the order determined by the getOrder() method.

As follows:

@Bean
public GlobalFilter customFilter(a) {
    return new CustomGlobalFilter();
}

public class CustomGlobalFilter implements GlobalFilter.Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("custom global filter");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder(a) {
        return -1; }}Copy the code

5 Everything is customizable

Spring allows developers to customize Predicate, GatewayFilter, and GlobalFilter.

5.1 Customizing Predicate

public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {

    public MyRoutePredicateFactory(a) {
        super(Config.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        // grab configuration from Config object
        return exchange -> {
            //grab the request
            ServerHttpRequest request = exchange.getRequest();
            //take information from the request to see if it
            //matches configuration.
            return matches(config, request);
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here}}Copy the code

5.2 Customizing GatewayFilter

Pre filters:

public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {

    public PreGatewayFilterFactory(a) {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            //If you want to build a "pre" filter you need to manipulate the
            //request before calling chain.filter
            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
            //use builder to manipulate the request
            return chain.filter(exchange.mutate().request(builder.build()).build());
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here}}Copy the code

Filter for Post:

public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

    public PostGatewayFilterFactory(a) {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                ServerHttpResponse response = exchange.getResponse();
                //Manipulate the response in some way
            }));
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here}}Copy the code

5.3 Customizing GlobalFilter

@Bean
public GlobalFilter customGlobalFilter(a) {
    return (exchange, chain) -> exchange.getPrincipal()
        .map(Principal::getName)
        .defaultIfEmpty("Default User")
        .map(userName -> {
          //adds header to proxied request
          exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
          return exchange;
        })
        .flatMap(chain::filter);
}

@Bean
public GlobalFilter customGlobalPostFilter(a) {
    return (exchange, chain) -> chain.filter(exchange)
        .then(Mono.just(exchange))
        .map(serverWebExchange -> {
          //adds header to response
          serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
              HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
          return serverWebExchange;
        })
        .then();
}
Copy the code

6 Project Usage

Add dependencies:

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

Configure Main to start the application:

package com.pkslow.cloud.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayService {
    public static void main(String[] args) { SpringApplication.run(GatewayService.class, args); }}Copy the code

Configuring routes:

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: pkslow
        uri: https://www.pkslow.com
        predicates:
        - Path=/pkslow/**
        filters:
        - RewritePath=/pkslow(? 
      
       .*),
       /$\{segment}
Copy the code

After startup, it can be accessed normally:

7 summary

The Spring Cloud Gateway is powerful enough to meet most microservices scenarios, so it’s worth knowing.

Please check the code: github.com/LarryDpk/pk…


Reference: official website