头图
How many requests were intercepted by the gateway;

1. Introduction to Gateway

In the microservice architecture, the gateway service usually provides dynamic routing, as well as core capabilities such as flow control and request identification. In the previous chapters, I mentioned the use process of the Zuul component, but the current Gateway component is a more conventional choice, and the following will focus on the Gateway detailed analysis of the practice;

01.png

From the perspective of the architectural model, no matter what technical components the gateway adopts, it provides a layer of interception and verification capabilities between the client and the business service. However, compared with Zuul, the Gateway provides more powerful functions and excellent performance. ;

Based on practical scenarios, functionally, the gateway focuses more on the requester's legal verification, traffic control, and IP-level interception. From an architectural perspective, it is usually necessary to provide flexible routing mechanisms, such as grayscale and load balancing strategies. etc., and based on the message mechanism, system-level security notification, etc.;

02.png

The following focuses on the three nodes of the client, the gateway layer, and the facade service, and analyzes the usage details of the Gateway, that is, the client sends a request to the gateway, and the gateway is routed to the facade service for processing;

2. Dynamic Routing

1. Basic Concepts

Routing : As the core capability of the gateway, from the perspective of source code structure, it includes ID, request URI, assertion set, filter set, etc.;

 public class RouteDefinition {
    private String id;
    private URI uri;
    private List<PredicateDefinition> predicates = new ArrayList<>();
    private List<FilterDefinition> filters = new ArrayList<>();
}

Assertion + filtering : Usually, the matching rules of the request are defined in the assertion, and the processing action of the request is defined in the filtering. In terms of structure, it is a set of names and parameters, and supports shortcut configuration;

 public class PredicateDefinition {
    private String name;
    private Map<String, String> args = new LinkedHashMap<>();
}

public class FilterDefinition {
    private String name;
    private Map<String, String> args = new LinkedHashMap<>();
}

2. Configure routing

In the way of configuration, add facade service route, in the way of path matching, if the request path is wrong, the assertion fails, StripPrefix is set to 1, that is, the first /facade is removed from the filter parameter;

 spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: facade
          uri: http://127.0.0.1:8082
          predicates:
            - Path=/facade/**
          filters:
            - StripPrefix=1

The execution principle is as follows:

03.png

Here is a configuration file to set the routing policy of the facade service, which specifies the path method, and provides a variety of routing samples in the Gateway document, such as: Header, Cookie, Method, Query, Host etc. assertion method;

3. Coding method

Manage routing policies based on coding. The Gateway document also provides a variety of reference examples. If routing services are few and fixed, the configuration method can be solved. If there are many routing services and need to be dynamically added, the library table-based method is more suitable. ;

 @Configuration
public class GateConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("facade",r -> r.path("/facade/**").filters(f -> f.stripPrefix(1))
                .uri("http://127.0.0.1:8082")).build();
    }
}

4. Library table loading

In conventional applications, it is a common way to read the routing policy from the library table, define the routing factory class and implement the RouteDefinitionRepository interface, involving three core methods of loading, adding, and deleting, and then based on the service class Read data from the library and convert it to RouteDefinition object;

04.png

 @Component
public class DefRouteFactory implements RouteDefinitionRepository {
    @Resource
    private ConfigRouteService routeService ;
    // 加载
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        return Flux.fromIterable(routeService.getRouteDefinitions());
    }
    // 添加
    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(routeDefinition -> { routeService.saveRouter(routeDefinition);
            return Mono.empty();
        });
    }
    // 删除
    @Override
    public Mono<Void> delete(Mono<String> idMono) {
        return idMono.flatMap(routeId -> { routeService.removeRouter(routeId);
            return Mono.empty();
        });
    }
}

The library table management method is adopted in the source code repository. More details of the code logic can be moved to Git for reference, and will not be pasted too much here;

3. Custom routing strategy

  • Custom assertion , inherit the AbstractRoutePredicateFactory class, note that the name ends with RoutePredicateFactory , rewrite the apply method to execute specific matching rules;
 @Component
public class DefCheckRoutePredicateFactory extends AbstractRoutePredicateFactory<DefCheckRoutePredicateFactory.Config> {
    public DefCheckRoutePredicateFactory() {
        super(Config.class);
    }
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                log.info("DefCheckRoutePredicateFactory:" + config.getName());
                return StrUtil.equals("butte",config.getName());
            }
        };
    }
    @Data
    public static class Config { private String name; }
    @Override
    public List<String> shortcutFieldOrder() { return Collections.singletonList("name"); }
}
  • Custom filtering , inherit the AbstractNameValueGatewayFilterFactory class, note that the name ends with GatewayFilterFactory , rewrite the apply method to execute specific filtering rules;
 @Component
public class DefHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
    @Override
    public GatewayFilter apply(AbstractNameValueGatewayFilterFactory.NameValueConfig config) {
        return (exchange, chain) -> {
            log.info("DefHeaderGatewayFilterFactory:"+ config.getName() + "-" + config.getValue());
            return chain.filter(exchange);
        };
    }
}
  • Configure the loading method . Here assertion and filtering are the fast configuration methods, so the naming convention should be followed by the Gateway;
 spring:
  cloud:
    gateway:
      routes:
        - id: facade
          uri: http://127.0.0.1:8082
          predicates:
            - Path=/facade/**
            - DefCheck=butte
          filters:
            - StripPrefix=1
            - DefHeader=cicada,smile

Generally speaking, policy customization for assertion and filtering is required in application-level systems to provide support at the business or architecture level, and to complete more detailed rule verification, especially when multiple versions of the same service are running in parallel, it can be better management routing strategy, so as to avoid the influence between branches;

Fourth, the global filter

The filtering used in routing is GatewayFilter , and the actual gateway also provides GlobalFilter global filter, although it is very similar in structure, but its responsibilities are fundamentally different;

  • Global Filter 1: Print Request ID
 @Component
@Order(1)
public class DefOneGlobalFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("request-id:{}",exchange.getRequest().getId()) ;
        return chain.filter(exchange);
    }
}
  • Global Filter 2: Print Request URI
 @Component
@Order(2)
public class DefTwoGlobalFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("request-uri:{}",exchange.getRequest().getURI()) ;
        return chain.filter(exchange);
    }
}

As the first layer in the microservice architecture system to receive requests, the Gateway gateway can define many strategies to protect the security of the system, such as current limiting of high-concurrency interfaces, third-party authorization verification, IP interception when maliciously attacked, etc. Try to intercept illegal requests in the gateway to ensure the security and stability of the system.

5. Reference source code

 应用仓库:
https://gitee.com/cicadasmile/butte-flyer-parent

组件封装:
https://gitee.com/cicadasmile/butte-frame-parent

已注销
479 声望53 粉丝