Welcome to my GitHub

Github.com/zq2599/blog…

Content: all original article classification summary and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.;

This paper gives an overview of

  • This article is part 8 of the Spring Cloud Gateway In Action series. After learning about filters, we will complete the last section of filters: RequestRateLimiter.

  • The Token Bucket Algorithm is based on the Token Bucket Algorithm. The Token Bucket Algorithm is based on the Token Bucket Algorithm. The Token Bucket Algorithm is the Token Bucket Algorithm. The bucket has a limited capacity for tokens, such as 20 at most, and the rate at which tokens enter the bucket is constant (note the difference from the leaky bucket algorithm), such as 10 tokens per second, and each request at the bottom will be processed only if it gets a token:

RequestRateLimiter Basic routine

  • The steps to use the RequestRateLimiter filter are simple:
  1. Prepare available Redis
  2. Maven or gradle add dependent org. Springframework. The boot: spring – the boot – starter – data – redis – reactive
  3. Determine by what dimension, for example by the username parameter in the request, by writing an implementation of the KeyResolver interface
  4. Configure the application.yml file and add filters
  • That’s how to use the RequestRateLimiter filter. Easy? Next, let’s code and verify

Download the source code

  • The full source code for this article can be downloaded at GitHub with the following address and link information (github.com/zq2599/blog…
The name of the link note
Project home page Github.com/zq2599/blog… The project’s home page on GitHub
Git repository address (HTTPS) Github.com/zq2599/blog… The project source warehouse address, HTTPS protocol
Git repository address (SSH) [email protected]:zq2599/blog_demos.git The project source warehouse address, SSH protocol
  • The git project has multiple folders. The source code for this project is in the spring-cloud-tutorials folder, as shown in the red box below:

  • Spring-cloud-tutorials have several sub-projects under the folder. This code is gateway-RequeStratelimiter, as shown in the red box below:

The preparatory work

  • To better demonstrate the effect of Gateway, add a New Web interface to the service provider provider-hello code (hello.java) that accepts an input parameter:
    @GetMapping("/userinfo")
    public String userInfo(@RequestParam("username") String username) {
        return Constants.HELLO_PREFIX + "" + username + "," + dateStr();
    }
Copy the code
  • We will use the above interface for the following tests;

coding

  • A new child project, gateway-RequeStratelimiter, was added under the parent project spring-cloud-tutorials, whose pom.xml would read as follows: The focus is on org. Springframework. The boot: spring – the boot – starter – data – redis – reactive:

      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-cloud-tutorials</artifactId>
        <groupId>com.bolingcavalry</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway-requestratelimiter</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.bolingcavalry</groupId>
            <artifactId>common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
    </dependencies>
</project>
Copy the code
  • In the configuration file application.yml, note that several parameters of RequestRateLimiter have been annotated in Chinese:
server:
  # service port
  port: 8081
spring:
  application:
    name: circuitbreaker-gateway
  # redis configuration
  redis:
    host: 192.168. 5043.
    port: 6379

  cloud:
    gateway:
      routes:
        - id: path_route
          uri: http://127.0.0.1:8082
          predicates:
            - Path=/hello/**
          filters:
            - name: RequestRateLimiter
              args:
              	# Tokens are loaded into buckets at a rate of 100 per second, equivalent to QPS
                redis-rate-limiter.replenishRate: 100
                The bucket can hold 200 tokens, which is equivalent to the peak. Note that 200 tokens can be fetched from the bucket in the first second, but only 100 tokens can be fetched from the bucket in the second second, because the bucket loading rate is 100 tokens per second
                redis-rate-limiter.burstCapacity: 200
                Number of tokens required per request
                redis-rate-limiter.requestedTokens: 1
Copy the code
  • Customizeconfig. Java specifies the stream limiting dimension. Here, the stream limiting is based on the value of the request parameter username, assuming that in the real request, half of the request username is Tom, and the other half of the request username is Jerry. According to the application.yml configuration, Tom’s QPS is 10 and Jerry’s QPS is 10:
package com.bolingcavalry.gateway.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
import java.util.Objects;

@Configuration
public class CustomizeConfig {
    @Bean
    KeyResolver userKeyResolver(a) {
        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("username")); }}Copy the code
  • No nutritional startup class RequestRateLimiterApplication. Java:
package com.bolingcavalry.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RequestRateLimiterApplication {
    public static void main(String[] args) { SpringApplication.run(RequestRateLimiterApplication.class,args); }}Copy the code
  • Once you’ve written your code, you can verify it;

Verify (Bucket capacity equals bucket loading speed)

  • Verify that the bucket capacity is equal to the bucket inbound speed. Modify the application.yml file in the gateway-RequeStratelimiter application. ReplenishRate and Redis-rate-limitter. burstCapacity are equal to 100, i.e., the bucket size is 100 and the number of tokens added per second is also 100

  • Make sure redis is started and is consistent with the configuration in application.yml

  • Starting nacOS (provider-Hello dependency)

  • Start the service provider provider-hello

  • Start the gateway – requestratelimiter

  • To simulate web requests, I use Apache Benchmark for Windows:

www.apachelounge.com/download/VS…

  • After the above files are decompressed, run the following command on the console to enter Apache24\bin, which means that 10000 requests are sent to the specified address and the concurrent number is 2:
ab -n 10000 -c 2 http://localhost:8081/hello/userinfo? username=TomCopy the code
  • The console output is as follows, it can be seen that in less than eight seconds, only 800 succeeded, proving that the current limit is in line with expectations:

Verification (Bucket capacity greater than bucket loading speed)

  • Next, try limiting the flow when the bucket capacity is greater than the bucket speed, which is an important reference for controlling the peak response

  • Modify the application.yml file of the gateway-RequeStratelimiter application, the replenishRate of redis-rate-limitter. replenishRate remains unchanged at 100. But redis-rate-limiter.burstCapacity is changed to 200, which means 100 tokens are still put in every second, but the bucket capacity is doubled

  • Restart the application gateway-RequeStratelimiter

  • Send 10000 requests to the specified address with 2 concurrent requests:

ab -n 10000 -c 2 http://localhost:8081/hello/userinfo? username=TomCopy the code
  • The test results are as shown in the following figure, which is consistent with expectations. All tokens in the bucket can be used to support the scenario where the peak value exceeds QPS:

Verify (traffic limiting based on the dimension of username)

  • Then verify that the dimension of stream limiting is based on the value of the request parameter username

  • Let’s open two command lines and send requests simultaneously (fast). The first one has username equal to Tom, and the second one is equal to Jerry. Theoretically, if both are completed in 8 seconds, then 900 requests per command will succeed

  • Select * from user where username = ‘username’; select * from user where username = ‘username’;

  • At this point, Spring Cloud Gateway traffic limiting practice has been completed, such a simple and easy to use traffic limiting scheme, I hope to bring reference to your learning and use

You are not alone, Xinchen original accompany all the way

  1. Java series
  2. Spring series
  3. The Docker series
  4. Kubernetes series
  5. Database + middleware series
  6. The conversation series

Welcome to pay attention to the public number: programmer Xin Chen

Wechat search “programmer Xin Chen”, I am Xin Chen, looking forward to enjoying the Java world with you…

Github.com/zq2599/blog…