[Spring special session] practice guide for Gateway whole process development of "Spring cloud" microservice Gateway service (2.2.X)

Development guidelines and instructions

This practice is mainly in version 2.2.0 Build on build-snapshot, which provides an API gateway built on the Spring ecosystem.

Introduction to Spring Cloud Gateway

The goal of Spring Cloud Gateway is to route to the API in a simple and effective way, and provide some crosscutting concerns, such as security, monitoring, system performance and elasticity.

Introduction to API gateway

The reason for the emergence of API gateway is the emergence of micro service architecture. Different micro services generally have different network addresses, and external clients may need to call the interfaces of multiple services to complete a business requirement. If the client is allowed to communicate directly with each micro service, there will be the following problems:

  1. The client will request different microservices many times, which increases the complexity of the client.
  2. There are cross domain requests, which are relatively complex to process in certain scenarios.
  3. Authentication is complex, and each service needs independent authentication.
  4. It is difficult to refactor. With the iteration of the project, it may be necessary to re divide the microservices.
    • For example, you might merge multiple services into one or split a service into multiple. If the client communicates directly with the microservice, the refactoring will be difficult to implement.
  5. Some micro services may use firewall / browser unfriendly protocols, and direct access will be difficult.

These problems can be solved by API gateway. API gateway is an intermediate layer between client and server. All external requests will pass through the API gateway layer first. In other words, business logic is more considered in the implementation of API, and security, performance and monitoring can be done by API gateway, which not only improves business flexibility but also does not lack security.

Spring cloud Gateway Technology Foundation

It is based on spring official Spring 5.0 and spring boot2 0 and Project Reactor. Spring Cloud Gateway aims to provide a simple, effective and unified API routing management method for microservice architecture. As a gateway in Spring Cloud ecosystem, Spring Cloud Gateway aims to replace Netflix Zuul. It not only provides a unified routing method, but also provides the basic functions of the gateway based on Filer chain, For example: safety, monitoring / embedding point, current limiting, etc.

How to reference Spring Cloud Gateway

maven coordinates are:

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

For details about building a system using the current Spring Cloud, if you introduce a starter but do not want to open the gateway, you can set:

spring.cloud.gateway.enabled=false. 

be careful

  1. Spring Cloud Gateway is built on Spring Boot 2.0, Spring WebFlux, and Project Reactor. Therefore, many familiar synchronization libraries (such as Spring Data and Spring Security) or patterns are not applicable to Spring Cloud Gateway.

  2. Spring Cloud Gateway requires the netty runtime provided by SpringBoot and SpringWebFlux. It no longer runs in the traditional Servlet container or a WAR package.

Route

The basic component block of the gateway is also the most basic part of the gateway. The routing information is composed of an ID, a destination URL, a group of assertion predictions and a group of filters. If the aggregation assertion is true, the route is matched, indicating the URL and configuration of the request.

Predicate

Assertion function in Java 8. The input type of the assertion function in the Spring Cloud Gateway is spring 5 ServerWebExchange in the 0 framework. The assertion function in Spring Cloud Gateway allows developers to define and match any information from http request, such as request header and parameters.

Java 8 Function Predicate. The input type is spring framework server webexchange This allows developers to match anything from HTTP requests, such as headers or parameters.

Filter

An instance of Spring Framework gateway filter constructed using a specific factory. Here, you can modify requests and responses before or after sending a downstream} request.

A standard Spring webFilter. There are two types of filters in Spring cloud gateway: Gateway Filter and Global Filter. The filter will modify the request and response.

understand:
  1. Predicate: request matching;
  2. Filter: filter and enhance the request or return.

The gateway provides API full hosting services and rich API management functions to assist enterprises in managing large-scale APIs to reduce management costs and security risks, including protocol adaptation, protocol forwarding, security policy, anti brushing, traffic, monitoring log and other functions. Generally speaking, the URL or interface information exposed by the gateway is collectively referred to as routing information.

How Spring Cloud Gateway works

Gateway client requests Spring Cloud Gateway. If Gateway Handler Mapping determines that the request matches the route, the request is sent to Gateway Web Handler. This Handler runtime sends requests to specific requests, which pass through the filter chain.

The reason why the filter chain is separated by dotted lines is that the filter can execute logic before or after sending the proxy request. Perform all "pre" filtering logic and then issue a proxy request. After a proxy request is made, the "post" filter logic is executed. If the URIs does not have a port set in the route, the default ports are set to 80 and 443 according to HTTP and HTTPS.

The Spring cloud Gateway sends a request. Then, find the route matching the request in the Gateway Handler Mapping and send it to the Gateway web handler. The Handler sends the request to our actual service through the specified filter chain, executes the business logic, and then returns.

Spring Cloud Gateway - route assertion factory

Spring Cloud Gateway matches routes as part of the spring Webflux handlermapping infrastructure. Spring Cloud Gateway contains many built-in route assertion factories. These assertions match HTTP requests with different attributes. Multiple route assertion factories can be combined and logically combined.

Before Route Predicate Factory

Before Route Predicate Factory has a time parameter, and this assertion matches the request that occurs before the time parameter.

This route matches the request before Jan 20, 2017 17:42 Mountain Time (Denver).

After Route Predicate Factory

After Route Predicate Factory has a time parameter, and this assertion matches requests that occur after the time parameter.

This route matches the request after Jan 20, 2017 17:42 Mountain Time (Denver).

Between Route Predicate Factory

Between route predict factory has two time parameters. This assertion matches requests that occur between these two times.

This route matching occurs between Jan 20, 2017 17:42 Mountain Time (Denver) and Jan 21, 2017 17:42 Mountain Time (Denver). Can be applied to maintenance windows.

Cookie Route Predicate Factory

Cookie Route Predicate Factory has two parameters, including cookie name and regular expression. This assertion matches cookies, including the given name and a value that conforms to a regular expression.

The route matching cookie name is chocolate, the cookie value is ch.p regular expression, matching chap,chbp, etc.

Header Route Predicate Factory

The Header Route Predicate Factory includes two parameters, including a regular expression of the header name and value. This assertion matches a header including the name and the request that matches the regular expression value.

The route matching header name is X-Request-Id and the value matches the \ d + expression (containing one or more numbers).

Host Route Predicate Factory

The Host route predict factory includes a list of parameter Host name patterns. This mode is an Ant style mode with "." As a separator. This assertion matches the Host header. In addition, there are two sources of Host header: the first is the request address; The second is to put the Host variable value in the http header.

URI template variables also support this format {sub} myhost. org.

This route matches the Host value www.somehost.com in the header file orgļ¼Œbeta.somehost.org or www.otherhost.com org. This example is the default port 80. If it is another port, it needs to be defined in the expression.

This assertion extracts the URI template variable (such as the child variable defined in the above example) as a mapping of names and values and places it in serverwebexchange In getattributes(), the key is serverwebexchangeutils URI_ TEMPLATE_ VARIABLES_ Attribute is defined in the attribute.

Add the following code example to the filter:
Map uri_template_variables_attribute=exchange.getAttribute(ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
   // Map variables=ServerWebExchangeUtils.getUriTemplateVariables(exchange);
     uri_template_variables_attribute.forEach((K,V)->{
            System.out.println("K:"+K+"--V:"+V);
      });
  • Visit Host: www.myhost.com org
  • Output result: K:sub – V:www

Filter regulator

The Global Filter interface has the same signature as the GatewayFilter. These are special filters that conditionally apply to all routes.

Combined Global Filter and GatewayFilter Ordering
  • When the request enters (and matches the route), the Filtering Web Handler adds all instances of GlobalFilter and all route specific instances of GatewayFilter to the filter chain.

  • This combined filter chain is through org springframework. core. The ordered interface. You can implement the getOrder() method or use the @ Order annotation.

Spring Cloud Gateway distinguishes the "request" and "response" stages of filter logic execution. The filter with the highest priority will be the first in the "request" stage and the last in the "response" stage.

There are three types of ANT wildcards:

Most of the above matching rule operation symbols are implemented by AntPathMatcher objects

private AntPathMatcher antPathMatcher = new AntPathMatcher();
  • ?: Match any single character
    • : matches 0 or any number of characters
  • **: matches characters from 0 and or more directories
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        //Mall api interface, verification user must log in
        if(antPathMatcher.match("/api/**/auth/**", path)) {
            List<String> tokenList = request.getHeaders().get("token");
            if(null == tokenList) {
                ServerHttpResponse response = exchange.getResponse();
                return out(response);
            } else {
//                Boolean isCheck = JwtUtils.checkToken(tokenList.get(0));
//                if(!isCheck) {
                    ServerHttpResponse response = exchange.getResponse();
                    return out(response);
//                }
            }
        }
        //Internal service interface, external access is not allowed
        if(antPathMatcher.match("/**/inner/**", path)) {
            ServerHttpResponse response = exchange.getResponse();
            return out(response);
        }
        return chain.filter(exchange);
    }

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

    private Mono<Void> out(ServerHttpResponse response) {
        JsonObject message = new JsonObject();
        message.addProperty("success", false);
        message.addProperty("code", 28004);
        message.addProperty("data", "Authentication failed");
        byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        //response.setStatusCode(HttpStatus.UNAUTHORIZED);
        //Specify the code, otherwise Chinese garbled code will appear in the browser
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}

Custom exception handling

When the service gateway calls the service, there may be some exceptions or the service is unavailable. The error information returned by it is unfriendly and needs to be overwritten.

ErrorHandlerConfig
@Configuration
@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
public class ErrorHandlerConfig {

    private final ServerProperties serverProperties;

    private final ApplicationContext applicationContext;

    private final ResourceProperties resourceProperties;

    private final List<ViewResolver> viewResolvers;

    private final ServerCodecConfigurer serverCodecConfigurer;

    public ErrorHandlerConfig(ServerProperties serverProperties,
                                     ResourceProperties resourceProperties,
                                     ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                        ServerCodecConfigurer serverCodecConfigurer,
                                     ApplicationContext applicationContext) {
        this.serverProperties = serverProperties;
        this.applicationContext = applicationContext;
        this.resourceProperties = resourceProperties;
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
        JsonExceptionHandler exceptionHandler = new JsonExceptionHandler(
                errorAttributes,
                this.resourceProperties,
                this.serverProperties.getError(),
                this.applicationContext);
        exceptionHandler.setViewResolvers(this.viewResolvers);
        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
        return exceptionHandler;
    }
}

reference material

  • https://blog.csdn.net/qq_37989738/article/details/107205863

Keywords: Spring Spring Cloud Microservices

Added by irvieto on Sat, 15 Jan 2022 23:01:59 +0200