An overview of the

Gateway is based on Netty asynchronous communication and uses the Webflux framework to process requests.

The release notes for Spring Cloud and Spring Boot used in this article

Version Overview: Spring-Boot 2.4.2 Spring-Cloud 2020.0.1

Service registration: Eureka-client

Service meltdown: reactor-Resilience4J

This article mainly uses a demo to give a brief introduction to the core functions of Gateway.

Demo project address Github address

Gateway Core Functions

A routing.

  1. Configuring Load Balancing
uri: lb://SERVICE-MEMBER
Copy the code

In this case, the lb is using load balancing, because I am using Eureka-client 3.0.1 internally using loadbalancer as the load balancing frame.

  1. Configuration assertion
predicates:
	# Route assertion Assertion is made on the interface that meets the condition
	- Path=/member/**
Copy the code

Predicates all the configuration information below are assertions about the service node interface, we can also assert parameters, cookies, headers and other aspects

  1. Configuring filters
filters:
  # fuse
  - name: CircuitBreaker
  args:
  name: myCircuitBreaker
  fallbackUri: forward:/fallback
Copy the code

Gatway also provides the configuration of filters and supports custom filters to control routing rules

2. The authentication

The main way to implement authentication is through GlobalFilter. The following is a simple example to determine whether our cookies contain login information. If it is included, use it for login. If it is not, return UNAUTHORIZED

  1. To authenticate user logins, define global filters first
/** * Custom login filter to determine whether to log in **@author zhengsh
 * @dateThe 2021-01-31 * /
public class LoginFilter implements GlobalFilter.Ordered {
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    MultiValueMap<String, HttpCookie> cookies = exchange.getRequest().getCookies();
    for (Map.Entry<String, List<HttpCookie>> cookie : cookies.entrySet()) {
      // If the cookie contains login information, the cookie passes
      if (cookie.getKey().equals("login")) {
        System.out.println(1);
        return chain.filter(exchange);
      }
    }
    System.out.println(2);
    / / 401
    ServerHttpResponse response = exchange.getResponse();
    response.setStatusCode(HttpStatus.UNAUTHORIZED);
    return response.setComplete();
  }


  @Override
  public int getOrder(a) {
    return -1; }}Copy the code

Downgrade/circuit breaker

Resilience4j degraded the service

filters:
  # fuse
  - name: CircuitBreaker
  args:
  name: myCircuitBreaker
  fallbackUri: forward:/fallback
Copy the code

Resilience4j is a lightweight fault-tolerant library inspired by Hystrix. In distributed systems, many calls will inevitably fail, such as timeout, one session, etc. Resilience4j can ensure that the whole service will not fail in the case of a dependency problem, so as to avoid cascading failures and improve the resiliency of distributed systems.

“Circuit breaker” itself is a kind of switching device. When a service unit fails, through the fault monitoring of the circuit breaker (similar to a safety fuse), it returns to the calling method a FallBack that meets the expectation and can be handled, rather than waiting for a long time or running out of exceptions that the calling method cannot handle. This ensures that the threads of the service caller are not tied up unnecessarily for long periods of time, thus preventing failures from spreading across the distributed system and causing an avalanche effect.

4. Current limit

Traffic limiting is implemented using the Redislimiter algorithm of the Gateway

Configuration parameters:

filters:
  # token bucket
  - name: RequestRateLimiter
  KeyResolver: userKeyResolver
  args:
    redis-rate-limiter.replenishRate: 10
    redis-rate-limiter.burstCapacity: 20
    redis-rate-limiter.requestedTokens: 1
Copy the code

UserKeyResolver definition

@Bean
public KeyResolver userKeyResolver(a) {
  return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
Copy the code

Access mode:

http://127.0.0.1:4001/member/test?user=100