-
Notifications
You must be signed in to change notification settings - Fork 327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rate Limit proposal #2039
Rate Limit proposal #2039
Conversation
Signed-off-by: Ilya Lobkov <ilya.lobkov@konghq.com>
Signed-off-by: Ilya Lobkov <ilya.lobkov@konghq.com>
Signed-off-by: Ilya Lobkov <ilya.lobkov@konghq.com>
|
docs/proposals/rate-limit.md
Outdated
Since it is a local rate limiting we have to set it on the destination side. It could be challenging to support | ||
`source` selector, but still quite possible for HTTP. We already set header `x-kuma-tags` to identify the source for | ||
FaultInjections, I believe the same approach will work for RateLimit. For TCP most likely we’ll have a limitation | ||
on `source` selector unless it’s possible to somehow use SANs but still this is mTLS only. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the main use case that users and customers are looking for?
Is it about throttling web
so it won't send more than 100 req/s to backend
if app is misbehaving or is it about protecting backend
that it does not receive more than X req/s?
If former, then we can go with Ilya's proposal, but if it is about protecting backend
then it should be
type: RateLimit
name: rt-1
mesh: default
selectors:
- match:
kuma.io/service: backend # apply on backend for any traffic
conf:
tcp:
connections: 100 # how many connections are allowed per 'period'
period: 1s
http: ...
To give more examples with the current approach
---
type: RateLimit
name: rt-1
mesh: default
sources:
- match:
kuma.io/service: web
destinations:
- match:
kuma.io/service: backend
conf:
http:
requests: 100 # how many requests are allowed per 'period'
period: 1s
---
type: RateLimit
name: rt-1
mesh: default
sources:
- match:
kuma.io/service: another-client
destinations:
- match:
kuma.io/service: backend
conf:
http:
requests: 100 # how many requests are allowed per 'period'
period: 1s
web AND another-client are able to execute 100 req/s.
type: RateLimit
name: rt-1
mesh: default
sources:
- match:
kuma.io/service: '*'
destinations:
- match:
kuma.io/service: backend
conf:
http:
requests: 100 # how many requests are allowed per 'period'
period: 1s
any instance of a service can execute 100 req/s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the approach with sources
and destinations
can't have a policy like this:
type: RateLimit
name: rt-1
mesh: default
sources:
- match:
kuma.io/service: *
destinations:
- match:
kuma.io/service: backend
conf:
http:
requests: 100 # how many requests are allowed per 'period'
period: 1s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can, but again. This is different than
type: RateLimit
name: rt-1
mesh: default
selectors:
- match:
kuma.io/service: backend # apply on backend for any traffic
conf:
tcp:
connections: 100 # how many connections are allowed per 'period'
period: 1s
http: ...
applied on the backend.
In your case, any instance can send up to 100 req/s to backend
.
In the case above, one instance of backend
can process 100 req/s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but I proposed to apply rate-limiting on the destination side, selecting by sources
might be tricky but I think it's possible to implement at least for HTTP
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jakubdyszkiewicz @subnetmarco I reflected this discussion as 3 different options in the proposal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rate limiting is for protection of the destination. Although the destination service may want to assign different limits to different sources. Use cases are:
backend
will only handle 100 req/s from any source.backend
will only handle 100 req/s from any source, but a specificbackend-app
source should be able to make 200req/s.
Signed-off-by: Ilya Lobkov <ilya.lobkov@konghq.com>
append: false | ||
``` | ||
|
||
Same as [Design 1](#Design 1), but rate-limiter is configured on the `destination` side. This allows user to protect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is a local rate limit on each backend instance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's correct
This also needs to support rate limiting on external services, therefore in this case applied at the source and not at the destination. |
Also, we need to support multiple backends for rate limiting. In this case is
|
The implementation that I have been working on in #2083 is done on the destination. |
IMHO the different places rate limits can be applied are useful for different operational reasons. Since it's likely that we will end up with different kinds of rate limit (e.g global, egress, ingress), we just need to be clear about it in the API design and documentation. |
Is this done since #2083 is merged? |
Proposal on the new Rate Limit policy (or maybe Rate Limiting?)