SpringCloud microservice Gateway

1, Introduction to Gateway

(1) Official website: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

(2) Introduction to the official website:
Gateway is an API gateway service built on the Spring ecosystem and is based on technologies such as Spring 5, Spring Boot 2 and Project Reactor. Gateway aims to provide a simple and effective way to route APIs and provide some powerful filter functions
For example: fusing, current limiting, Retry, etc

Spring Cloud gateway is a new project of Spring Cloud. It is a gateway developed based on Spring 5.0+Spring Boot 2.0 and Project Reactor. It aims to provide a simple and effective unified API routing management method for microservice architecture.
I
As a gateway in the Spring Cloud ecosystem, Spring Cloud gateway aims to replace Zuul. In Spring Cloud versions above 2.0, the latest performance versions above Zuul 2.0 are not integrated, and Zuul 1.0 is still used X is an older version of non Reactor mode. In order to improve the performance of the gateway,

Spring cloud gateway is implemented based on WebFlux framework, and Netty, a high-performance Reactor mode communication framework, is used at the bottom of WebFlux framework.

The goal of Spring Cloud Gateway is to provide a unified routing method, and the Filter chain based method provides the basic functions of the gateway, such as security, monitoring / indicators, and current limiting.

The Spring Cloud Gateway uses the reactor Netty responsive programming component in Webflux, and the Netty communication framework is used at the bottom

Specific functions: reverse proxy, authentication, flow control, fuse, log monitoring

(3) Spring cloud gateway has the following features

Based on Spring Framework 5, Project Reactor and Spring Boot 2.0, it is built with dynamic routing and can match any request attribute

You can specify Predicate and Filter for routes to integrate the circuit breaker function of Hystrix

Integrate Spring Cloud service discovery

Easy to write Predicate and Filter, request current limiting function

Support path rewriting

(4) The difference between spring cloud gateway and Zuul

Before the official version of Spring Cloud Finchley, the gateway recommended by Spring Cloud was Zuul provided by Netflix
1,Zuul 1.x. Is an API Gateway based on blocking I/O
2,Zuul 1.x uses blocking architecture based on Servlet 2.5. It does not support any long connections (such as WebSockets). Zuul's design pattern is more similar to Nginx. V О All operations are executed by selecting one of the working threads. The request thread is blocked until the working thread is completed. However, the difference is that Nginx is implemented in C + +, zuul is implemented in Java, and the JVM itself will load slowly for the first time, which makes zuul's performance relatively poor.
3,Zuul 2. The X concept is more advanced. It wants to be non blocking based on Netty and support long connections, but the spring cloud has not been integrated yet. The performance of Zuul 2 x is better than that of zuul 1 X has been greatly improved. In terms of performance, according to the official benchmark, the RPS (requests per second) of Spring Cloud Gateway is 1.6 times that of zuul.
4. Spring Cloud Gateway is built on Spring Framework 5, Project Reactor and Spring Boot2 and uses non blocking API s.
5. Spring Cloud Gateway also supports WebSocket and is closely integrated with spring to have a better development experience

(5) Three core concepts of Gateway

Route: route is the basic module for building a gateway. It consists of ID, target URI, a series of assertions and filters. If the assertion is true, the route will be matched

Predicate: it refers to java.util.function.Predicate of java8. Developers can match all contents in HTTP requests (such as request headers or request parameters). If the requests match assertions, they will route

Filter: refers to the instance of GatewayFilter in the Spring framework. Using the filter, you can modify the request before or after it is routed.

(6) Gateway workflow

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

The reason why the filters are separated by dotted lines is that the filters may execute business logic before ("pre") or after ("post") sending proxy requests. Filters of type "pre" can perform parameter verification, permission verification, traffic monitoring, log output, protocol conversion, etc. in "post" Type of Filter can be used to modify the response content and response header, log output, traffic monitoring and so on.

Core logic: route forwarding + execution filter chain

2, Getting started configuration

(1) pom dependency

 <dependencies>
        <!--newly added gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
       
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

(2) yml configuration

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
      routes:
        - id: payment_routh #The ID of the route. There are no fixed rules, but it is required to be unique. It is recommended to match the service name
#          uri: http://localhost:8001 # matches the routing address of the service
          uri: lb://cloud-payment-service
          predicates:
            - Path=/payment/get/**   #Assert that the path matches the route


        - id: payment_routh2
#          uri: http://localhost:8001
          uri: lb://cloud-payment-service
          predicates:
            - Path=/payment/lb/**   #Assert that the path matches the route
#            - Header=X-Request-Id, \d+ #Regular expression with X-Request-Id attribute and integer value in request header
#            - Host=**.atguigu.com
#            - Method=GET
#            - Query=username, \d+ #You must have a parameter name and be a positive integer to route
#            - Cookie=username,gaozhi  #curl http://localhost:9527/payment/lb --cookie "username=gaozhi"
#            - After=2021-09-27T11:11:50.233+08:00[Asia/Shanghai]  #Take effect at a fixed time. Take effect after a certain time
#            - Before=2021-09-27T12:11:50.233+08:00[Asia/Shanghai] #Take effect at a fixed time
#            - Between=2021-09-27T11:11:50.233+08:00[Asia/Shanghai],2021-09-27T11:12:50.233+08:00[Asia/Shanghai]  #Effective within a certain period of time, the front must be less than the back

(3) YML configuration description
There are two configuration methods for Gateway routing. One is to configure in the configuration file yml, as shown in the above configuration, and the other is to inject the Bean of RouteLocator into the code. Examples are as follows:

@Configuration
public class GateWayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("path_rote_atguigu", r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
        return routes.build();
    }

    @Bean
    public RouteLocator customRouteLocator2(RouteLocatorBuilder builder){
        return   builder.routes().route("path_rote_atguigu2", t -> t.path("/guoji").uri("http://news.baidu.com/guonei")).build();
    }

}

3, Dynamic routing through microservice name

By default, the Gateway will create a dynamic route with the name of the micro service on the registry as the path according to the service list of the registry for forwarding, so as to realize the function of dynamic routing. It should be noted that the protocol of uri is lb, which means that the load balancing function of Gateway is enabled.

yml configuration, lb://serviceName is the load balancing uri that spring cloud gateway automatically creates for us in microservices

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
      routes:
        - id: payment_routh #The ID of the route. There are no fixed rules, but it is required to be unique. It is recommended to match the service name
          #uri: http://localhost:8001 # matches the routing address of the service
          uri: lb://cloud-payment-service
          predicates:
            - Path=/payment/get/**   #Assert that the path matches the route

        - id: payment_routh2
          #uri: http://localhost:8001 # matches the routing address of the service
          uri: lb://cloud-payment-service
          predicates:
            - Path=/payment/lb/**   #Assert that the path matches the route

4, Use of Predicate


1.After Route Predicate

  - After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]

2.Before Route Predicate

 - Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]

3.Between Route Predicate

-Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] ,  2020-03-08T10:59:34.102+08:00[Asia/Shanghai]

4.Cookie Route Predicate

 - Cookie=username,atguigu    #And the Cookie can only be accessed if username=zhangshuai

5.Header Route Predicate

- Header=X-Request-Id, \d+   #Regular expression with X-Request-Id attribute and integer value in request header

6.Host Route Predicate

  - Host=**.www.com

7.Method Route Predicate

- Method=GET

8.Path Route Predicate

- Path=/payment/lb/**   #Assert that the path matches the route

9.Query Route Predicate

  - Query=username, \d+ #You must have a parameter name and be a positive integer to route

5, Use of Filter

GatewayFilter Factories
iRoute fites all w the moifcation of the inccming HiTP requestor outgoing HiTTPresponse in scome manner. Route fltes are scoped to a paricuar route.Spring Cloud:Gateway includes many built-in GatewayFilter Factories.NOTE For more detailed examples on how to use any of the following filters, take a look at the unit tests.

The routing filter can be used to modify incoming HTTP requests and returned HTTP responses. The routing filter can only be used by specifying routes.
Spring Cloud Gateway has built-in multiple routing filters, which are generated by the factory class of GatewayFilter

Filter of Spring Cloud Gateway
1. Life cycle: before business logic - pre, after business logic - post
2. Type: single configuration gateway filter, global configuration GlobalFilter

Common GatewayFilter

AddRequestParameter
yml configuration

Custom filter

Custom global GlobalFilter: Global logging, unified gateway authentication

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter,Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        log.info("*********come in MyLogGateWayFilter: "+new Date());
        String uname = exchange.getRequest().getQueryParams().getFirst("username");
        if(StringUtils.isEmpty(username)){
            log.info("*****User name is Null illegal user,(┬_┬)");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);//Give someone a response
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

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

Keywords: Spring Cloud Microservices gateway

Added by drunkencelt on Mon, 20 Dec 2021 12:11:49 +0200