An article to understand Spring Cloud Gateway (from getting started to giving up)

First understand what is a gateway

​ In a traditional monolithic application, all requests are handled by one application, so there is no concept of a gateway. However, in the microservice architecture, each service has an address and port for providing external services, and has some common functions, such as: permission verification, logging, current limiting, circuit breaker, monitoring, etc. If each service is allowed to provide an interface independently. Coordinating and managing these interfaces will become very cumbersome and cause code duplication.

The gateway is used to solve these problems in the microservice architecture. The gateway provides a unified interface externally, and internally forwards the request to the appropriate service through the interaction with the registration center. The gateway is also responsible for some common functions, such as: permission verification, logging, current limiting, circuit breaker, monitoring, etc.

​ After introducing the concept of gateway, each microservice only needs to pay attention to its own business logic and does not need to pay attention to other functions. The operation of microservices is greatly simplified.

​ Spring cloud gateway is a very popular microservice gateway framework officially launched by Spring. Compared with other gateway service frameworks, Spring cloud gateway is easy to use, powerful, and easier to integrate with the Spring cloud ecosystem.

Get started quickly

It is very easy to get started with spring cloud gateway. Before we learn all about it, let's take a look at a simple example.

Create a spring boot project

Use spring initializr to create a spring boot project and select webflux and gateway dependencies.

Write a simple route

Add the following configuration in application.yml:

spring:
  cloud:
    gateway:
      routes:
        - id: path_route
          uri: http://www.baidu.com
          predicates:
            - Path=/get

Startup project

Start the project, visit http://localhost:8080/get, you can see that the page is loaded with the Baidu homepage.

The basic process of spring cloud gateway

Only by being familiar with the problems and basic processes to be solved by Spring Cloud gateway can we learn it better. The basic flow of the spring cloud gateway is shown in the following figure:
[External link image transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the image and upload it directly (img-qRcilN82-1675767528124)(img.png)]

When the client sends a request to Spring Cloud Gateway, spring gateway will match the corresponding Gateway Web Handler according to the requested information and routing rules. The Handler will process the request through a filter link, and the filter can process the data before or after the request agent sends it.

The core concept of Spring Cloud Gateway

routing

Routing is the basic module of Spring Cloud Gateway, which consists of an ID, a target URI, a series of assertions and a series of filters. When a request enters Spring Cloud Gateway, the system will try to match all the routes in order, and when the match is successful, the corresponding filter chain will be executed. Then forward to the target URI.

In fact, when using Spring Cloud Gateway, our main job is to specify routing rules. That is, specify the route's ID, target URI, assertion, and filter. There are two ways to specify routing rules, one is to specify in the configuration file, and the other is to specify by encoding.

Configuration file specifies routing rules

Add the following configuration in application.yml:

spring:
  cloud:
    gateway:
      routes:
        - id: path_route
          uri: http://www.baidu.com
          predicates:
            - Path=/get
        - id: host_route
          uri: http://www.baidu.com
          predicates:
            - Host=**.baidu.com

Encoding specifies routing rules

In Spring Cloud Gateway, we can specify routing rules by coding, which is more flexible, and we can dynamically add and delete routing rules at runtime.

@Configuration
public class GatewayConfig {
    
    

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    
    
        return builder.routes()
                .route("path_route", r -> r.path("/get")
                        .uri("http://www.baidu.com"))
                .route("host_route", r -> r.host("*.baidu.com")
                        .uri("http://www.baidu.com"))
                .build();
    }
}

Either way, in routing configuration, what we basically need to do is to specify assertions, set filters, specify jumps or handlers for processing.
Let's take a look at these concepts one by one.

Affirmation

Assertion is a boolean expression, its function is to judge whether the request satisfies the condition of the route. If the assertion is true, the route is matched, otherwise it is not. Assertions can be specified in configuration files or coded.

Configuration file specifies assertions

There are two ways to specify assertions in the configuration file, one is shortcut implementation, and the other is full implementation.

shortcut implementation

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

Full implementation

spring:
  cloud:
    gateway:
      routes:
        - id: after_route
          uri: https://example.org
          predicates:
            - name: Cookie
              args:
                name: mycookie
                regexp: mycookievalue

Through the above two methods, we can see that: the shortcut specifies the name and parameters of the assertion separated by commas, and the full method specifies the name and parameters of the assertion through the two attributes of name and args.

Encoding Specified Assertions

To specify assertions in coding, we can specify assertions through the PredicateSpec method, as follows:

@Configuration
public class GatewayConfig {
    
    

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    
    
        return builder.routes()
                .route("path_route", r -> r.path("/get").uri("http://www.baidu.com"))
                .route("host_route", r -> r.host("*.baidu.com").uri("http://www.baidu.com"))
                .build();
    }
}

In the above example, we specified two routing rules by coding, namely path_route and host_route. We programmatically set assertions, filters, and target URIs.

Summary of assertions

When you understand the intent of assertions and how to configure them, using assertions becomes very simple. Some commonly used built-in assertion factories, you can learn how to use them through the official website.
Official website address

filter

The filter is the core component of Spring Cloud Gateway, and its role is to modify the request before or after it is routed. The filters of Spring Cloud Gateway are divided into two types: GatewayFilter and GlobalFilter

  • GlobalFilter: A global filter that modifies the request before or after it is routed.
  • GatewayFilter: A local filter that acts on a single route and can modify the request before or after it is routed.

global filter

Global filters are filters that apply to all routes and can modify requests before or after they are routed. Spring Gateway has some global filters built in. In addition to the built-in common global filters, we can also customize the global filters. About the built-in global filter, you can go to the official website to learn about it one by one, or go to the official website to find it when you need a global filter. If there is no suitable then consider a custom filter.
Official website address

Configuration files specify global filters

spring:
  cloud:
    gateway:
      globalfilters:
        - name: AddRequestHeader
          args:
            name: X-Request-Global-Foo
            value: Global-Bar

Encoding specifies global filters

@Configuration
public class GatewayConfig {
    
    
    @Bean
    public GlobalFilter customGlobalFilter() {
    
    
        return (exchange, chain) -> {
    
    
            ServerHttpRequest request = exchange.getRequest().mutate().header("X-Request-Global-Foo", "Global-Bar").build();
            return chain.filter(exchange.mutate().request(request).build());
        };
    }
}

custom global filter

Custom filters need to implement the GatewayFilter interface, as follows:

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    
    

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        System.out.println("global filter");
        return chain.filter(exchange);
    }

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

In actual use, you can use or combine appropriate filters according to your own business needs.

local filter

Local filters are filters that act on a single route and can modify the request before or after it is routed. Spring Gateway has some local filters built in. In addition to the built-in common local filters, we can also customize local filters.
About the built-in global filter, you can go to the official website to learn about it one by one, or go to the official website to find it when you need a global filter. If there is no suitable then consider a custom filter. Local filter official website address

Configure local filters in the configuration file

In the configuration file, in the defined Router, we specify the filter through Filters. In Filters, we can specify multiple filters, and the execution order of the filters is executed in accordance with the order in the Filters. In each filter, we specify the name and parameters of the filter by Name and Args. Or we can set the filter by Name = Args.

spring:
  cloud:
    gateway:
      routes:
        - id: path_route
          uri: http://www.baidu.com
          predicates:
            - Path=/get
          filters:
            - AddRequestHeader=X-Request-Foo, Bar
            - AddResponseHeader=X-Response-Foo, Bar
            - DedupeResponseHeader=Foo
            - Hystrix=fooCommand
            - PrefixPath=/httpbin
            - PreserveHostHeader
            - RemoveRequestHeader=Foo
            - RemoveResponseHeader=Foo
            - RewritePath=/foo/(?<segment>.*), /$\{
    
    segment}
            - RewriteResponseHeader=Location, http://newlocation.org
            - RequestRateLimiter=5, 1, SECONDS
            - Retry=3
            - SaveSession
            - SecureHeaders
            - SetPath=/foo/{
    
    segment}
            - SetRequestHeader=X-Request-Foo, Bar
            - SetResponseHeader=X-Response-Foo, Bar
            - SetStatus=401
            - StripPrefix=1
            - StripRequestHeader=Foo
            - StripResponseHeader=Foo
            - Weight=foo, 5

encoding using local filters

In coding, we can specify filters through Filters. In Filters, we can specify multiple filters, and the execution order of the filters is executed in accordance with the order in the Filters.

@Configuration
public class GatewayConfig {
    
    

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    
    
        return builder.routes()
                .route("path_route", r -> r.path("/get")
                        .filters(f -> f.addRequestHeader("X-Request-Foo", "Bar")
                                .addResponseHeader("X-Response-Foo", "Bar"))
                        .uri("http://www.baidu.com"))
                .build();
    }
}

custom local filter

Custom filters need to implement the GatewayFilter interface, as follows:

@Component
public class MyGatewayFilter implements GatewayFilter, Ordered {
    
    

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        System.out.println("gateway filter");
        return chain.filter(exchange);
    }

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

Handler Function

By configuring assertions and filters, Spring Cloud Gateway can route requests to specified services. However, if we want to process requests directly in Spring Cloud Gateway instead of routing requests to specified services, then we need to use Handler Function.

Handler Function is a concept in WebFlux. It is a function that receives a ServerRequest object and returns a Mono object. In Spring Cloud Gateway, we can process requests through Handler Function instead of routing requests to specified services.

Customize a Handler Function

To customize a Handler Function, you need to implement the HandlerFunction interface, as follows:

@Component
public class MyHandlerFunction implements HandlerFunction<ServerResponse> {
    
    

    @Override
    public Mono<ServerResponse> handle(ServerRequest request) {
    
    
        return ServerResponse.ok().body(BodyInserters.fromObject("hello world"));
    }
}

UseHandler Function

import org.springframework.beans.factory.annotation.Autowired;

@Configuration
public class GatewayConfig {
    
    
    @Autowired
    private MyHandlerFunction myHandlerFunction;
    @Bean
    public RouterFunction<ServerResponse> htmlRouterFunction() {
    
    
        return RouterFunctions.route(RequestPredicates.path("/fallback"), myHandlerFunction));
    }
}

Summarize

Spring Cloud Gateway is quite simple and convenient to use in microservices. For most uses, we only need to configure Spring Cloud Gateway to connect to the registry, and then configure routing rules. Even in many cases, the routing configuration does not need to be designed. It will match the request with the service of the registry by default. If it is matched, it will be automatically routed to the corresponding service.

Guess you like

Origin blog.csdn.net/aofengdaxia/article/details/128924106