• Limit the flow of the requested target URL (e.g., how many calls to a URL are allowed per minute)
  • Limit the flow of client access IP addresses (for example, how many requests are allowed per minute for an IP address)
  • Limit traffic for certain users or user groups (for example, non-VIP users can only call an API 100 times per minute)
  • Multi-dimensional mixed current limiting. At this point, it is necessary to implement some flow limiting rules orchestration mechanism. And, or, not equal relationship.

introduce

Spring-cloud-zuul-ratelimit is an extension that integrates with Zuul to provide distributed traffic limiting policies. It only takes a few lines of configuration in YAML to enable traffic limiting

<dependency> <groupId>com.marcosbarbero.cloud</groupId> <artifactId>spring-cloud-zuul-ratelimit</artifactId> < version > 1.3.4. RELEASE < / version > < / dependency >Copy the code

Supported traffic limiting granularity

  • Service granularity (default, traffic limiting for the current service module)

  • User granularity (see summary at the end of this article for details)

  • ORIGIN granularity (ORIGIN requested by the user as granularity control)

  • Interface granularity (request the address of the interface as granularity control)

  • The above granularity is freely combined and can support a variety of situations.

  • If that’s not enough, customize the RateLimitKeyGenerator implementation.

Public String key(final HttpServletRequest Request, final Route Route, final RateLimitProperties.Policy policy) { final List<Type> types = policy.getType(); final StringJoiner joiner = new StringJoiner(":");
    joiner.add(properties.getKeyPrefix());
    if(route ! = null) { joiner.add(route.getId()); }if(! types.isEmpty()) {if(types.contains(Type.URL) && route ! = null) { joiner.add(route.getPath()); }if(types.contains(Type.ORIGIN)) { joiner.add(getRemoteAddr(request)); } // This combination is summarized at the end of the article.if (types.contains(Type.USER)) {
            joiner.add(request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : ANONYMOUS_USER);
        }
    }
    return joiner.toString();
}
Copy the code

Supported storage modes

  • InMemoryRateLimiter – Uses ConcurrentHashMap as the data store
  • ConsulRateLimiter – Use Consul for data storage
  • RedisRateLimiter – Uses Redis as the data store
  • SpringDataRateLimiter – Uses the database as the data store

Current limiting configuration

  • Limit Indicates the number of access permissions in a specified period of time
  • Quota specifies the total number of access times allowed per request.
  • Refresh-interval Specifies the unit time
zuul:
  ratelimit:
    key-prefix: your-prefix 
    enabled: true 
    repository: REDIS 
    behind-proxy: true
    policies:
      myServiceId:
        limit: 10
        quota: 20
        refresh-interval: 30
        type:
          - user
        
Copy the code

The above configuration means that 10 accesses are allowed within 30 seconds, and the total request time is required to be less than 20 seconds

Results show

Yaml configuration:

zuul:
  ratelimit:
    key-prefix: pig-ratelimite 
    enabled: true 
    repository: REDIS 
    behind-proxy: true
    policies:
      pig-admin-service:
        limit: 2
        quota: 1
        refresh-interval: 3
Copy the code

Dynamic figure left left left left left down down down down

Data structures in Redis note the red font

conclusion

  • The Spring Boot Actuator provides the service status and dynamically sets the current limiting switch
  • The source code can be referred to: gitee.com/log4j/pig
  • Implementation of user traffic limiting: If your project integrates Shiro or Spring Security frameworks, the Request domain UserPrincipal will be maintained automatically. If it is your own framework, please maintain the Request domain UserPrincipal after successful login to use user-granularity traffic limiting. The default value is anonymous