GateWay basic knowledge and simple application

GateWay

API gateway refers to the unified entrance of the system. It encapsulates the internal structure of the application and provides unified services for the client. Some public logic that has nothing to do with the functions of the business itself can be implemented here, such as authentication, authentication, monitoring, routing and forwarding etc.

Official document address : https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/

Examples of functions that can be realized by the API gateway:

  • Focus on Stability and Security
    • global flow control
    • log statistics
    • Prevent SQL injection
    • Prevent web attacks
    • Mask tool scan
    • Black and white IP list
    • Certificate/encryption and decryption processing
  • provide better service
    • service level flow control
    • Service downgrade and circuit breaker
    • Routing and load balancing, grayscale strategy
    • Service filtering, aggregation and discovery
    • Authorization Verification and User Level Policies
    • Business rules and parameter validation
    • multi-level caching strategy

Spring Cloud Gateway is the second-generation gateway framework officially launched by Spring Cloud, which is positioned to replace Netflix Zuul1.0. Compared with Zuul, Spring Cloud Gateway provides better performance and more powerful functions.
Spring Cloud Gateway is a responsive API gateway implemented by WebFlux + Netty + Reactor. It doesn't work in a traditional servlet container, nor can it be built into a war package.
Spring Cloud Gateway aims to provide a simple and effective API routing management method for the microservice architecture, and provides basic functions of the gateway based on Filter, such as security authentication, monitoring, current limiting, and so on.

Features

  • Built on Spring Framework 5, Project Reactor and Spring Boot 2.0
  • Dynamic routing: able to match any request attribute
  • Support path rewriting
  • Integrate Spring Cloud service discovery function (Nacos, Eruka)
  • Can integrate flow control downgrade function (Sentinel, Hystrix)
  • Easy-to-write Predicate (assertion) and Filter (filter) can be specified on the route

Core idea

  • Routing (route) Routing is the most basic part of the gateway. Routing information includes an ID, a destination URI, a set of assertion factories, and a set of Filters. If the assertion is true, the requested URL matches the configured route.
  • Assertion (predicates) The assertion function in Java8, the type of assertion function in SpringCloud Gateway is ServerWebExchange in the Spring5.0 framework. The assertion function allows developers to define any information that matches the Http request, such as request headers and parameters.
  • Filter (Filter) The filter in SpringCloud Gateway is divided into Gateway FilIer and Global Filter. Filter can process requests and responses.

working principle

insert image description here

The execution process is as follows:

  1. Gateway Client sends a request to Gateway Server.
  2. The request will first be extracted by the HttpWebHandlerAdapter and assembled into a gateway context.
  3. The context of the gateway is then passed to the DispatcherHandler, which is responsible for dispatching the request to the RoutePredicateHandlerMapping.
  4. RoutePredicateHandlerMapping is responsible for route lookup, and judges whether the route is available according to the route assertion.
  5. If the assertion succeeds, the filter chain is created and called by FilteringWebHandler.
  6. The request will go through the PreFilter-microservice-PostFilter method once, and finally return the response.

First experience with GateWay

  • Build a SpringBoot project

  • import dependencies

    #父工程中已经引入的 spring cloud 其他的依赖
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  • add configuration file

    server:
      port: 8088
    spring:
      application:
        name: api-gateway
      cloud:
        # gateway的配置
        gateway:
          # 路由规则
          routes:
            - id: order_route   # 路由的唯一标识,路由到order
              uri: http://localhost:8010   # 需要转发的地址
              # 断言规则 用于路由规则的匹配
              predicates:
                - Path=/order-serv/**
                  # http://localhost:8088/order-serv/order/add  路由到 ↓
                  # http://localhost:8010/order-serv/order/add
              filters:
                - StripPrefix=1  # 转发之前去掉一级路径 order-serv
                # http://localhost:8010/order/add
    
  • Access configured rules via GateWay
    insert image description here

GateWay integrates nacos

  • add dependencies

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
  • Modify the configuration file

    server:
      port: 8088
    spring:
      application:
        name: api-gateway
      cloud:
        # gateway的配置
        gateway:
          # 路由规则
          routes:
            - id: order_route   # 路由的唯一标识,路由到order
              uri: lb://order-service  # 需要转发的地址  # lb是从nacos中按照名称获取服务,并遵循负载均衡策略
              # 断言规则 用于路由规则的匹配
              predicates:
                - Path=/order-serv/**
                  # http://localhost:8088/order-serv/order/add  路由到 ↓
                  # http://localhost:8010/order-serv/order/add
              filters:
                - StripPrefix=1  # 转发之前去掉一级路径 order-serv
                # http://localhost:8010/order/add
        # 添加nacos配置信息
        nacos:
          server-addr: 192.168.2.7:8848
          discovery:
            username: nacos
            password: nacos
            namespace: public
    

Affirmation

When requesting the gateway, use the assertion to match the request, if the match is successful, the route will be forwarded, and if the match fails, 404 will be returned.

Built-in assertion factory

  • Assertion factory based on Datetime type
    This type of assertion is judged according to time, there are three main types:

    1. AfterRoutePredicateFactory: Receive a date parameter to determine whether the requested date is later than the specified date

      - After=2017-01-20T17:42:47.789-07:00[America/Denver]
      
    2. BeforeRoutePredicateFactory: Receive a date parameter to determine whether the requested date is earlier than the specified date

      - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
      
    3. BetweenRoutePredicateFactory: Receive two date parameters to determine whether the requested date is within the specified time period

      - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
      
  • The remote address-based assertion factory
    RemoteAddrRoutePredicateFactory: receives an IP address segment and determines whether the requesting host address is in the address segment

    ‐ RemoteAddr=192.168.1.1/24
    
  • Cookie-based assertion factory
    CookieRoutePredicateFactory: Receives two parameters, cookie name and a regular expression. Judgment request. Whether the cookie has the given name and value matches the regular expression.

     ‐Cookie=chocolate, ch.
    
  • Header-based assertion factory
    HeaderRoutePredicateFactory: Receives two parameters, header name and regular expression. Determine if the request header has the given name and the value matches the regular expression.

     ‐Header=X‐Request‐Id, \d+
    
  • Host-based assertion factory
    HostRoutePredicateFactory: Receives a parameter, the host name pattern. Determine whether the requested Host meets the matching rules.

     ‐Host=**.testhost.org
    
  • MethodRoutePredicateFactory , an assertion factory based on the Method request method
    : receives a parameter to determine whether the request type matches the specified type.

     ‐Method=GET
    
  • PathRoutePredicateFactory , an assertion factory based on the Path request path
    : receives a parameter to determine whether the URI part of the request satisfies the path rule.

     ‐Path=/foo/{
          
          segment}
    
  • The assertion factory QueryRoutePredicateFactory based on Query request parameters
    : receives two parameters, request param and regular expression, and judges whether the request parameter has the given name and the value matches the regular expression.

     ‐Query=baz, ba.
    
  • WeightRoutePredicateFactory , an assertion factory based on route weight
    : receives a [group name, weight], and then forwards routes in the same group according to the weight.

     routes:
     ‐id: weight_route1
      uri: host1
      predicates:
     ‐Path=/product/**
     ‐Weight=group3, 1
     ‐id: weight_route2
      uri: host2
      predicates:
     ‐Path=/product/**
     ‐Weight= group3, 9
    

Custom Assertion Factory

  1. Custom assertion factories must be handed over to spring management
  2. The custom assertion factory class name must end with RoutePredicateFactory (the convention is greater than the configuration idea)
  3. Inherit the AbstractRoutePredicateFactory abstract class
  4. The custom assertion factory internally declares a static inner class, and the declaration attribute is used to receive the corresponding assertion information in the configuration file
  5. Data binding using the shortcutFieldOrder method
  6. Make logical judgments in applay
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {
    
    


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

    public Predicate<ServerWebExchange> apply(Config config) {
    
    
        return new GatewayPredicate() {
    
    
            public boolean test(ServerWebExchange serverWebExchange) {
    
    
                return config.getName().equals("zhangsan");
            }

            public String toString() {
    
    
                return String.format("MyRoute: param=%s", config.getName());
            }
        };
    }

    public List<String> shortcutFieldOrder() {
    
    
        return Collections.singletonList("name");
    }

    public static class Config{
    
    
        private String name;

        public String getName() {
    
    
            return name;
        }

        public void setName(String name) {
    
    
            this.name = name;
        }
    }
}

filter

built-in filter

Gateway has many built-in filter factories, through which we can perform some business logic processors, such as adding and removing response headers, adding and removing parameters, etc.

There are examples of filters on the official website, please refer to the official website

https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gatewayfilter-factories

filter factory effect parameter
AddRequestHeader Add Header to the original request Header name and value
AddRequestParameter Add request parameters to the original request Parameter name and value
AddResponseHeader Add Header to raw response Header name and value
DedupeResponseHeader Eliminate duplicate values ​​in response headers Header names and deduplication strategies that need to be deduplicated
Hystrix Introducing Hystrix's circuit breaker protection for routing The name of the HystrixCommand
FallbackHeaders Add specific exception information to the request header of fallbackUri Header name
PrefixPath Prefix the original request path prefix path
PreserveHostHeader Add a preserveHostHeader=true attribute to the request, and the routing filter will check this attribute to decide whether to send the original Host none
RequestRateLimiter Used to limit the flow of requests, the current limiting algorithm is token bucket keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus
RedirectTo Redirects the original request to the specified URL http status code and redirected url
RemoveHopByHopHeadersFilter Delete a series of headers specified by the IETF organization for the original request It is enabled by default, and you can specify which headers to delete only by configuration
RemoveRequestHeader Remove a header for the original request Header name
RemoveResponseHeader Remove a header for the original response Header name
RewritePath Rewrite the original request path The original path regular expression and the regular expression of the rewritten path
RewriteResponseHeader Rewrite a Header in the original response Header name, regular expression of value, rewritten value
SaveSession Force a WebSession::save operation before forwarding the request none
SecureHeaders Add a series of security response headers to the original response None, support modifying the value of these security response headers
SetPath Modify the original request path modified path
SetResponseHeader Modify the value of a Header in the original response Header name, modified value
SetStatus Modify the status code of the original response HTTP status code, which can be a number or a string
StripPrefix The path used to truncate the original request Use a number to indicate the number of paths to truncate
Retry Retry with a different response retries、statuses、methods、series
RequestSize Sets the size of the largest request packet allowed to be received. If the request packet size exceeds the set value, return 413 Payload Too Large Request packet size, the unit is byte, the default value is 5M
ModifyRequestBody Modify the original request body content before forwarding the request Modified request body content
ModifyResponseBody Modify the content of the original response body Modified response body content

custom filter

The custom filter is similar to the previous custom assertion factory process.

The custom filter adds the response header, MyGatewayFilter: test filter

code show as below:

@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.MyConfig> {
    
    

    public MyGatewayFilterFactory() {
    
    
        super(MyGatewayFilterFactory.MyConfig.class);
    }

    @Override
    public GatewayFilter apply(MyConfig config) {
    
    
        return new GatewayFilter() {
    
    
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
                String name = exchange.getRequest().getQueryParams().getFirst("name");
                if(StringUtils.isNotBlank(name)){
    
    
                    if (config.getValue().equals(name)){
    
    
                        exchange.getResponse().getHeaders().set("MyGatewayFilter","test filter");
                        return chain.filter(exchange);
                    }else{
    
    
                        exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
                        exchange.getResponse().setComplete();
                    }
                }
                //正常请求
                return chain.filter(exchange);
            }
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
    
    
        return Arrays.asList("value","key");
    }

    public static class MyConfig{
    
    
        private String value;
        private String key;

        public String getValue() {
    
    
            return value;
        }

        public void setValue(String value) {
    
    
            this.value = value;
        }

        public String getKey() {
    
    
            return key;
        }

        public void setKey(String key) {
    
    
            this.key = key;
        }
    }
}

The configuration file is as follows:

server:
  port: 8088
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: order_route
          uri: lb://order-service
          predicates:
            - Path=/order-serv/**
            - My=zhangsan
          filters:
            - My=zhangsan
            - StripPrefix=1
    nacos:
      server-addr: 192.168.2.7:8848
      discovery:
        username: nacos
        password: nacos
        namespace: public

View the effect:
insert image description here

global filter

The difference between local filters and global filters:

The GlobalFilter interface has the same interface definition as the GatewayFilter, but the GlobalFilter will act on all routes.

Local: For a certain route, it needs to be configured in the applied route.

Global: For all routing requests, once defined, it can take effect.

Gateway comes with a built-in global filter

insert image description here

custom global filter

Just implement the GlobalFilter interface;

@Component
public class MyGlobalLogFilter implements GlobalFilter {
    
    

    Logger log = LoggerFactory.getLogger(this.getClass());

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        log.info("访问路径为{}",exchange.getRequest().getPath().value());
        return chain.filter(exchange);
    }
}

insert image description here

Gateway integrates sentinel

Gateway current limiting official document

  • add dependencies

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
    </dependency>
    
  • add configuration file

        sentinel:
          transport:
            dashboard: 127.0.0.1:8080
    
  • Startup project, nacos, sentinel

  • View the effect
    insert image description here

There are some differences between this console and the simple project integration sentinel page, and the large configuration is basically the same. Some flow control rules can refer to my sentinel notes

Guess you like

Origin blog.csdn.net/weixin_45340300/article/details/128673134