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;
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.;
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:
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;
@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 withRoutePredicateFactory
, rewrite theapply
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 withGatewayFilterFactory
, rewrite theapply
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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。