Spring Cloud Gateway

1.1 direct

The content of this paper includes: microservice gateway traffic limit of 100,000 QPS, cross-domain, filter, token bucket algorithm.

Gateway is an essential technology in building microservices systems. From the early Zuul to the current Spring Cloud Gateway, gateways are indispensable.

Today I will settle down all the knowledge related to gateway, with an article summary clear, hope to love learning partners help.

This article mainly introduces gateway cross-domain configuration, gateway filter writing, gateway token bucket algorithm flow limiting [100,000 QPS per second]

First of all, what is a gateway

1.2 What is the Microservice Gateway?

This project provides a library for building an API Gateway on top of Spring WebFlux.

The gateway website:

Spring. IO/projects/sp…

There are many technologies for implementing microservices gateways,

  • Nginx The Nginx (Engine X) is a high-performance HTTP and reverse proxy Web server that provides IMAP, POP3, and SMTP services
  • Zuul is a Load balancer from Netflix based on JVM routing and server side.
  • Spring-cloud-gateway is a spring-based gateway project produced by Spring. It integrates circuit breakers, path rewriting, and performs better than Zuul.

We use the gateway technology to seamlessly integrate spring Cloud-based microservices development.

1.3 Why do microservices use gateways?

Different microservices generally have different network addresses, and external clients may need to call the interfaces of multiple services to complete a business requirement. If clients are allowed to communicate directly with each microservice, the following problems will occur:

  1. The client requests different microservices multiple times, increasing the complexity of the client
  2. Cross-domain requests exist and are complicated to process in certain scenarios
  3. Authentication is complex and each service requires independent authentication
  4. It is difficult to refactor, and as the project iterations, microservices may need to be reclassified. For example, you might combine multiple services into one or split a service into multiple services. Refactoring can be difficult to implement if the client communicates directly with the microservice
  5. Some microservices may use firewall/browser-unfriendly protocols, making direct access difficult

These problems can be solved by gateway.

The gateway is the middle layer between the client and server, and all external requests pass through the gateway first. In other words, the implementation of API takes more consideration of business logic, while security, performance and monitoring can be done by gateway, which not only improves business flexibility but also does not lack security. The typical architecture diagram is shown in the figure:

1.4 Advantages of the microservice gateway

  • Security, only the gateway system external exposure, micro services can be hidden in the Intranet, through the firewall protection.
  • Easy to monitor. Monitoring data can be collected at the gateway and pushed to external systems for analysis.
  • Easy to authenticate. Authentication can be done on the gateway and then requests can be forwarded to the back-end microservice instead of authentication in each microservice.
  • Reduce the number of interactions between the client and each micro-service
  • Easy unified authorization.

1.5 summarize

Microservice gateway is a system, by exposing the microservice gateway system, it is convenient for us to carry out relevant authentication, security control, unified log processing, easy to monitor the related functions. Historical articles: 200 phase summary

Ii. Establishment and configuration of micro-service gateway

2.1 Microservice gateway Microservice construction

Because the system that we develop includes foreground system and backstage system, backstage system is used to administrator. Then we also need to call various micro-services, so we set up a gateway micro-service for the management background. Analysis is as follows:

Setting up steps:

(1) Depend on coordinate POM.xml:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Copy the code

(2) Start the bootstrap class GatewayApplication

@SpringBootApplication @EnableEurekaClient public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); }}Copy the code

(3) Create application.yml under Resources

spring:
  application:
    name: apigateway
  cloud:
    gateway:
      routes:
      - id: open
        uri: lb://open
        predicates:
        - Path=/open/** filters: - StripPrefix= 1 - id: system uri: lb://system predicates: - Path=/system/** filters: - StripPrefix = 1 server: port: 9999 eureka: client: service - url: defaultZone: http://127.0.0.1:10086/eureka instance: prefer-ip-address: trueCopy the code

Refer to the official manual:

Cloud. Spring. IO/spring – clou…

2.2 Cross-domain microservice gateway

In the startup class GatewayApplication, add the following cross-domain configuration code

@Bean
public CorsWebFilter corsFilter() {
    CorsConfiguration config = new CorsConfiguration();
    config.addAllowedMethod("*");// Support all methods
    config.addAllowedOrigin("*");// Cross-domain processing allows all domains
    config.addAllowedHeader("*");// All headers are supported

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
    source.registerCorsConfiguration("/ * *", config);// Match all requests

    return new CorsWebFilter(source);
}
Copy the code

Microservice gateway filter

We can achieve some logical processing through the gateway filter, such as IP blacklist and whitelist interception, specific address interception, etc. The following code makes two filters, and sets the order.

(1) IpFilter is created in the gateway microservice without other configuration. It takes effect after registering with the Spring container

@Component
public class IpFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        InetSocketAddress remoteAddress = request.getRemoteAddress();
        //TODO Sets the IP whitelist
        System.out.println("ip:"+remoteAddress.getHostName());
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return 1; }}Copy the code

(2) UrlFilter is created in the gateway microservice without other configuration. It takes effect after registering with the Spring container

@Component
public class UrlFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String url = request.getURI().getPath();
        //TODO intercepts specific URL addresses
        System.out.println("url:"+url);
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 2; }}Copy the code

The gateway limits traffic to 100,000 requests per second

As we mentioned earlier, gateways can do a lot of things, such as limiting traffic, which can overwhelm our system when it is frequently requested.

So to solve this problem, you need to do traffic limiting on each microservice, but if you have a gateway, you can do traffic limiting on the gateway system, because all requests need to pass through the gateway system before they can be routed to the microservice.

4.1 Analysis of current limiting implementation ideas

Just look at the picture, very simple!

4.2 Introduction to the token bucket algorithm

Token bucket algorithm is one of the more common traffic limiting algorithms, which is roughly described as follows:

1) All requests need to get an available token before they can be processed;

2) Add the token to the bucket at a certain rate according to the flow limiting size;

3) The bucket sets the maximum limit for placing tokens. When the bucket is full, newly added tokens are discarded or rejected;

4) After the request is reached, the token in the token bucket should be obtained first, and then other business logic can be carried out after holding the token. After processing the business logic, the token will be deleted directly;

5) The token bucket has a minimum limit. When the number of tokens in the bucket reaches the minimum limit, the token will not be deleted after the request is processed to ensure sufficient flow limiting

The diagram below:

There are many techniques to implement this algorithm, Guava is one of them, and the Redis client also has its implementation. Historical articles: 200 phase summary

4.3 Code implementation of gateway flow limiting

Requirement: Each IP address can only send 100,000 requests in 1 second. Any additional requests return 429 errors.

Code implementation:

(1) Spring Cloud Gateway is implemented by default using redis RateLimter flow limiting algorithm. So we’re going to use the redis dependency first
<! --redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> <version>2.13..RELEASE</version>
</dependency>
Copy the code
(2) Define KeyResolver

Add the following code to the GatewayApplicatioin bootstrap class: KeyResolver calculates the KEY for limiting traffic of a certain type.

    // Define a KeyResolver
    @Bean
    public KeyResolver ipKeyResolver() {
        return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                returnMono.just(exchange.getRequest().getRemoteAddress().getHostName()); }}; }Copy the code
(3) Modify the configuration item in application.yml to specify the configuration of limiting traffic and REDIS. The final configuration after modification is as follows:
spring:
  application:
    name: apigateway
  cloud:
    gateway:
      routes:
      - id: open
        uri: lb://open
        predicates:
        - Path=/open/** filters: -stripprefix = 1-name: RequestRateLimiter # Args: key-resolver: "#{@ipKeyResolver}" redis-rate-limiter.replenishRate: 1 redis-rate-limiter.burstCapacity: 1 - id: system uri: Lb ://system predicates: -path =/system/** filters: -stripprefix = 1 101.57.2.128 Port: 6379 server: port: 9999 Eureka: client: service-url: defaultZone: Instance: http://127.0.0.1:100/eureka -- - IP - address: trueCopy the code

Explanation:

  • BurstCapacity: total capacity of the token bucket.
  • ReplenishRate: Average replenishment rate of the token bucket per second.
  • Key-resolver: The name of the Bean object that parsers the key used to limit the flow. It uses SpEL expressions to get Bean objects from the Spring container based on #{@beanname}.

The stable rate burstCapacity is achieved by setting the same value in the replenishRate and.

When burstCapacity is set to higher than that, the temporary burst replenishRate can be allowed.

In this case, the rate limiter needs to be allowed for a period of time (according to the replenishRate) between bursts, as 2 consecutive bursts will result in Requests being discarded (HTTP 429 – Too Many Requests)

Key-resolver: “#{@userKeyresolver}” is used to specify which KeyResolver to use through the SPEL expression.

The configuration is as follows:

The token bucket filling rate is also the rate at which one token is added per second.

The maximum emergency can only be requested once a second, which can be adjusted according to the service.

(4) During the test, we need to pay attention to the service startup sequence, which depends on Redis, so we need to start Redis first
  • Start the redis
  • Start the registry
  • Start product microservices
  • Start the gateway.
  • Open a browser: http://localhost:9999/open
  • A quick refresh that returns a 429 error when more than 100,000 requests are sent in a second.

So the question is: how do you send 100,000 requests? We’ll find out next time.

From:

juejin.cn/post/6895201419805392909