What problems do we have without the gateway

If the client is allowed to interact directly with each micro-service, there will be the following problems:

  • Cross-domain requests exist and are complicated to process in certain scenarios
  • Authentication issues, each microservice requires independent authentication
  • Some microservices use firewalls or browser-unfriendly protocols, making direct access difficult

What problems can gateways solve for us

Unified access

  • Provide unified access service for all wireless applications
  • High performance, high concurrency, high availability
  • Load balancing, Dr Switchover, and remote survival

Traffic control

  • Service degradation
  • fusing
  • routing

Safety protection

  • Black and white list
  • Risk control brush, malicious brush and so on

Protocol adapter

  • Front-end system (HTTP, HTTPS), back-end system (RPC)
  • Long and short links are supported
  • Route the front-end request and respond to the result

GateWay GateWay Introduction

Spring Cloud Gateway is an API Gateway officially launched by Spring. The framework includes Spring5, SpringBoot2, Project Reactor, and Netty used by the underlying communication framework. When Spring Cloud Gateway was first launched, Netflix had already launched ZUUL, an API Gateway framework with similar functions. However, ZUUL had a disadvantage that the communication mode was blocked. Although it was later upgraded to non-blocking ZUUL2, However, since Spring Cloud Gateway has been launched for a period of time, it has not been widely used due to the lack of data and poor maintenance.

Related terms

The Route:

A set of rules is a metadata class with attributes such as URI, predicate, filter, and so on. \

Predicate:

This is an approach to Java8 functional programming, where the route rule takes effect when conditions are met.

The Filter:

Filter can be considered as the most core module of Spring Cloud Gateway. It is used to complete fusing, security, logical execution and network invocation, which are subdivided into Gateway Filter and Global Filter. The difference is whether a particular route rule is in effect or all route rules are in effect.

Routing rules

Path: Query: Method:

Datetime:

RemoteAddr:

Header:

Using dynamic configuration (using Eureka)

# # # filters

RewritePathGatewayFilterFactory

PrefixPathGatewayFilterFactory

StripPrefixGatewayFilterFactory

SetPathGatewayFilterFactory

AddRequestParameterGatewayFilterFactory

SetStatusGatewayFilterFactory

Custom filter

public class CustomGatewayFilter implements GatewayFilter, Ordered {/** * @param exchange * @param chain * @return */ @override public Mono<Void> Filter (ServerWebExchange Exchange, GatewayFilterChain chain) {system.out.println (" Custom gateway filter "); return chain.filter(exchange); } @override public int getOrder() {return 0; }}Copy the code
@Configuration public class GatewayRoutesConfiguration { public RouteLocator routeLocator(RouteLocatorBuilder builder) { Path ("/order") // Target uri.uri ("lb://app-order") // Register custom filters.filters (new) CustomGatewayFilter()) // Route ID, unique.id ("app-order")).build(); }}Copy the code

Custom global filters

@Component public class CustomGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {system.out.println (" Custom global filter "); return chain.filter(exchange); } @Override public int getOrder() { return 0; }}Copy the code

The source code parsing

The Spring Cloud Gateway receives the request and matches the routing rules, which are then handed to the Web Handler. The Web handler executes a series of filter logic.

The entrance

Gateway to the programming model is webflux + reactor, I on this piece of ability is limited, can not explain don’t explain (sweat) org. Springframework. Web. Reactive. DispatcherHandler# handle

public Mono<Void> handle(ServerWebExchange exchange) { if (this.handlerMappings == null) { return createNotFoundError();  } return Flux.fromIterable(this.handlerMappings) .concatMap(mapping -> mapping.getHandler(exchange)) .next() .switchIfEmpty(createNotFoundError()) .flatMap(handler -> invokeHandler(exchange, handler)) .flatMap(result -> handleResult(exchange, result)); }Copy the code

All WebFlux calls go through this interface.

Of all the implementation classes, this one belongs to the Gateway, and that’s it.

Private Route convertToRoute(RouteDefinition RouteDefinition) {// Predicates AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition); // getFilters List<GatewayFilter> gatewayFilters = getFilters(routeDefinition); // Encapsulate the contents of the Route and return the object route.async (routeDefinition).asyncpredicate (predicate).replacefilters (gatewayFilters).build(); }Copy the code

protected Mono<Route> lookupRoute(ServerWebExchange exchange) { return this.routeLocator.getRoutes() // individually Filter routes so that filterWhen error delaying is not a. ConcatMap (route -> Mono.just(route).filterWhen(r -> { // add the current route we are testing exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, r.getId()); return r.getPredicate().apply(exchange); })}Copy the code

All the way back

org.springframework.web.reactive.DispatcherHandler#handle

Public Mono<Void> Handle (ServerWebExchange exchange) exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR); List<GatewayFilter> gatewayFilters = route.getfilters (); List<GatewayFilter> combined = new ArrayList<>(this.globalfilters); // Add to global filter combined. AddAll (gatewayFilters); / / sorting AnnotationAwareOrderComparator. Sort (combined); if (logger.isDebugEnabled()) { logger.debug("Sorted gatewayFilterFactories: " + combined); } / / calls, the most classic responsibility of chain will be executed every global filter again return new DefaultGatewayFilterChain (combined) filter (exchange); }Copy the code

Forward requests

The ForwardRoutingFilter simply uses spring MVC’s capabilities and sends the request to a dispatcherHandler that finds the desired execution logic based on the path prefix.

Response to write

The core class for response write back is NettyWriteResponseFilter

conclusion

I just went through the general process, and I will continue to analyze the details according to the specific situation. I am not familiar with reactor programming, so I can only understand the general aspects, which will be filled in later.