spring cloud gateway is configured with Zuul RateLimit current limiting

Keywords: Spring less Redis

Reprinted from: https://www.jianshu.com/p/2fc92a929e8e

Narration

In order to prevent the API without token access from being called infinitely, some services need to be API restricted. It's like taking some interfaces for registration or sending verification codes. If they are called maliciously and infinitely, they will cause some expenses. Sending SMS or e-mail are all third-party interfaces. The more times they are used, the more expenses they will incur, which will directly lead to service crash. It is necessary to introduce current limiting configuration in spring cloud API gateway.

Solution

The dependence of Zuul RateLimit in pom file

<dependency>
    <groupId>com.marcosbarbero.cloud</groupId>
    <artifactId>spring-cloud-zuul-ratelimit</artifactId>
    <version>1.3.2.RELEASE</version>
</dependency>

yml configuration

//A more detailed explanation of the configuration is written below. Here is just a simple configuration. The following configuration can restrict the flow of services
zuul:
  routes: Your routing configuration
    test:
      path: 
      serviceId: 
  ratelimit:
    enabled: true
    policies:
      test: Routing name
        limit: Restriction times
        refresh-interval: Refresh time
        type: type

List

Locally configure one of your own services to access the API of the service only ten times in a minute. If it is more than ten times, the gateway will report an error

zuul:
  routes:
    test:
      path: /api/test/**
      serviceId: hscf-cloud-test-9457
  ratelimit:
    enabled: true
    policies:
      test:
        limit: 10
        refresh-interval: 60
        type: origin  Current limiting mode

Let's briefly analyze the source code

The RateLimit class inherits ZuulFilter, and the variables in it are the property values we configured in the yml file. Part of the source code in RateLimit. If the filterType is "pre", it means to intercept before each API access. The three variables, LIMIT_HEADER, warning_header, and RESET_HEADER, should be to obtain the number of accesses we have configured, and record the number of accesses remaining in the time.

public class RateLimitFilter extends ZuulFilter {
    public static final String LIMIT_HEADER = "X-RateLimit-Limit";
    public static final String REMAINING_HEADER = "X-RateLimit-Remaining";
    public static final String RESET_HEADER = "X-RateLimit-Reset";

    public String filterType() {
        return "pre";
    }
    public int filterOrder() {
        return -1;
    }
    public boolean shouldFilter() {
        return this.properties.isEnabled() && this.policy(this.route()).isPresent();
    }

Judgment is made in the main logic run(). First, use this.policy(route).ifPresent((policy) to determine whether the policy configuration information exists. If it exists, it will be read
Take the current limit value, return the remaining limit value, and finally determine whether the remaining limit value is less than 0. If it is less than 0, too many exceptions will be reported
TOO_MANY_REQUESTS(429, "Too Many Requests")

    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse response = ctx.getResponse();
        HttpServletRequest request = ctx.getRequest();
        Route route = this.route();
        this.policy(route).ifPresent((policy) -> {
            String key = this.rateLimitKeyGenerator.key(request, route, policy);
            Rate rate = this.rateLimiter.consume(policy, key);
            response.setHeader("X-RateLimit-Limit", policy.getLimit().toString());
            response.setHeader("X-RateLimit-Remaining", String.valueOf(Math.max(rate.getRemaining().longValue(), 0L)));
            response.setHeader("X-RateLimit-Reset", rate.getReset().toString());
            if(rate.getRemaining().longValue() < 0L) {
                ctx.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
                ctx.put("rateLimitExceeded", "true");
                throw new ZuulRuntimeException(new ZuulException(HttpStatus.TOO_MANY_REQUESTS.toString(), HttpStatus.TOO_MANY_REQUESTS.value(), (String)null));
            }
        });
        return null;
    }
. . . . . . 

Exception information of the console. The exception code is 429, that is, too many requests: too many requests (429, "too many requests")

Detailed configuration information interpretation of RateLimit

zuul:

    ratelimit:

        key-prefix: your-prefix  #Prefix corresponding to the key used to identify the request

        enabled: true

        repository: REDIS  #Corresponding storage type (used to store Statistics)

        behind-proxy: true  #After agency

        default-policy: #Optional - policies configured for all routes, unless policies is specifically configured

             limit: 10 #Optional - limit on the number of requests per refresh window

             quota: 1000 #Optional - request time limit per refresh time window (seconds)

              refresh-interval: 60 # Refresh time window time, default (seconds)

               type: #Optional current limiting mode

                    - user

                    - origin

                    - url

          policies:

                myServiceId: #Specific routes

                      limit: 10 #Optional - limit on the number of requests per refresh window

                      quota: 1000 #Optional - request time limit per refresh time window (seconds)

                      refresh-interval: 60 # Refresh time window time, default (seconds)

                      type: #Optional current limiting mode

                          - user

                          - origin

                          - url
  • url type flow restriction is distinguished by request path
  • origin is distinguished by client IP address
  • Users are distinguished by login user names, including anonymous users
21 original articles published, 30 praised, 80000 visitors+
Private letter follow

Posted by coalgames on Sat, 11 Jan 2020 00:54:04 -0800