Spring Cloud Zuul RateLimit
Module to enable rate limit per service in Netflix Zuul.
There are four built-in rate limit approaches:
- Authenticated User
- Uses the authenticated username or 'anonymous'
- Request Origin
- Uses the user origin request
- URL
- Uses the request path of the downstream service
- Global configuration per service:
- This one does not validate the request Origin, Authenticated User or URI
- To use this approach just don't set param 'type'
Note: It is possible to combine Authenticated User, Request Origin and URL just adding multiple values to the list
Usage
This project is available on maven central
Add the dependency on pom.xml
<dependency>
<groupId>com.marcosbarbero.cloud</groupId>
<artifactId>spring-cloud-zuul-ratelimit</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
Add the following dependency accordingly to the chosen data storage:
- Redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- Consul
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul</artifactId>
</dependency>
- Spring Data JPA
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
- InMemory
ForInMemory
implementation there's no need to add any extra dependency other thancom.marcosbarbero.cloud:spring-cloud-zuul-ratelimit
Sample configuration
zuul:
ratelimit:
key-prefix: your-prefix
enabled: true
repository: REDIS
behind-proxy: true
default-policy: #deprecated - please use "default-policy-list"
limit: 10 #optional - request number limit per refresh interval window
quota: 1000 #optional - request time limit per refresh interval window (in seconds)
refresh-interval: 60 #default value (in seconds)
type: #optional
- user
- origin
- url
default-policy-list: #optional - will apply unless specific policy exists
- limit: 10 #optional - request number limit per refresh interval window
quota: 1000 #optional - request time limit per refresh interval window (in seconds)
refresh-interval: 60 #default value (in seconds)
type: #optional
- user
- origin
- url
policies: #deprecated - please use "policy-list"
myServiceId:
limit: 10 #optional - request number limit per refresh interval window
quota: 1000 #optional - request time limit per refresh interval window (in seconds)
refresh-interval: 60 #default value (in seconds)
type: #optional
- user
- origin
- url
policy-list:
myServiceId:
- limit: 10 #optional - request number limit per refresh interval window
quota: 1000 #optional - request time limit per refresh interval window (in seconds)
refresh-interval: 60 #default value (in seconds)
type: #optional
- user
- origin
- url
Available implementations
There are four implementations provided:
InMemoryRateLimiter
- usesConcurrentHashMap
as data storageConsulRateLimiter
- uses Consul as data storageRedisRateLimiter
- uses Redis as data storageSpringDataRateLimiter
- uses Spring Data as data storage
Common application properties
Property namespace: zuul.ratelimit
Property name | Values | Default Value |
---|---|---|
enabled | true/false | false |
behind-proxy | true/false | false |
key-prefix | String | ${spring.application.name:rate-limit-application} |
repository | CONSUL, REDIS, JPA, IN_MEMORY | IN_MEMORY |
default-policy | Policy | - |
policies | Map of Policy | - |
default-policy-list | List of Policy | - |
policy-list | Map of Lists of Policy | - |
Policy properties:
Property name | Values | Default Value |
---|---|---|
limit | number of calls | - |
quota | time of calls | - |
refresh-interval | seconds | 60 |
type | [ORIGIN, USER, URL] | [] |
Further Customization
This section details how to add custom implementations
Key Generator
If the application needs to control the key strategy beyond the options offered by the type property then it can
be done just by creating a custom RateLimitKeyGenerator
implementation adding further qualifiers or something
entirely different:
@Bean
public RateLimitKeyGenerator rateLimitKeyGenerator(final RateLimitProperties properties) {
return new DefaultRateLimitKeyGenerator(properties) {
@Override
public String key(HttpServletRequest request, Route route, RateLimitProperties.Policy policy) {
return super.key(request, route, policy) + ":" + request.getMethod();
}
};
}
Error Handling
This framework uses some 3rd party applications to store and control the rate limit access, as it does not has control
over those applications and they can fail once a while the framework itself handles the failure in the class
DefaultRateLimiterErrorHandler
just by adding some error logs.
If there is a need to handle the errors differently, it can be achieved just by defining a custom RateLimiterErrorHandler
bean, e.g:
@Bean
public RateLimiterErrorHandler rateLimitErrorHandler() {
return new DefaultRateLimiterErrorHandler() {
@Override
public void handleSaveError(String key, Exception e) {
// custom code
}
@Override
public void handleFetchError(String key, Exception e) {
// custom code
}
@Override
public void handleError(String msg, Exception e) {
// custom code
}
}
}
Contributing
Spring Cloud Zuul Rate Limit is released under the non-restrictive Apache 2.0 license, and follows a very standard Github development process, using Github tracker for issues and merging pull requests into master. If you want to contribute even something trivial please do not hesitate, but follow the guidelines below.
Adding Project Lombok Agent
This project uses Project Lombok to generate getters and setters etc. Compiling from the command line this shouldn't cause any problems, but in an IDE you need to add an agent to the JVM. Full instructions can be found in the Lombok website. The sign that you need to do this is a lot of compiler errors to do with missing methods and fields.
Code of Conduct
This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to marcos.hgb@gmail.com.
Acknowledgement
Footnote
Any doubt open an issue.
Any fix send me a Pull Request.