Skip to content

Commit 4ec90c5

Browse files
mpljuliensjbdoumenjou
authored andcommitted
Add rate limiter, rename maxConn into inFlightReq
Co-authored-by: Julien Salleyron <[email protected]> Co-authored-by: Jean-Baptiste Doumenjou <[email protected]>
1 parent a8c73f7 commit 4ec90c5

File tree

30 files changed

+1418
-650
lines changed

30 files changed

+1418
-650
lines changed

docs/content/assets/styles/extra.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ h3 {
3434
font-weight: bold !important;
3535
}
3636

37+
.md-typeset h5 {
38+
text-transform: none;
39+
}
40+
3741
figcaption {
3842
text-align: center;
3943
font-size: 0.8em;
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
# InFlightReq
2+
3+
Limiting the Number of Simultaneous In-Flight Requests
4+
{: .subtitle }
5+
6+
![InFlightReq](../assets/img/middleware/inflightreq.png)
7+
8+
To proactively prevent services from being overwhelmed with high load, a limit on the number of simultaneous in-flight requests can be applied.
9+
10+
## Configuration Examples
11+
12+
```yaml tab="Docker"
13+
labels:
14+
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
15+
```
16+
17+
```yaml tab="Kubernetes"
18+
apiVersion: traefik.containo.us/v1alpha1
19+
kind: Middleware
20+
metadata:
21+
name: test-inflightreq
22+
spec:
23+
inFlightReq:
24+
amount: 10
25+
```
26+
27+
```json tab="Marathon"
28+
"labels": {
29+
"traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10"
30+
}
31+
```
32+
33+
```yaml tab="Rancher"
34+
# Limiting to 10 simultaneous connections
35+
labels:
36+
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
37+
```
38+
39+
```toml tab="File (TOML)"
40+
# Limiting to 10 simultaneous connections
41+
[http.middlewares]
42+
[http.middlewares.test-inflightreq.inFlightReq]
43+
amount = 10
44+
```
45+
46+
```yaml tab="File (YAML)"
47+
# Limiting to 10 simultaneous connections
48+
http:
49+
middlewares:
50+
test-inflightreq:
51+
inFlightReq:
52+
amount: 10
53+
```
54+
55+
## Configuration Options
56+
57+
### `amount`
58+
59+
The `amount` option defines the maximum amount of allowed simultaneous in-flight request.
60+
The middleware will return an `HTTP 429 Too Many Requests` if there are already `amount` requests in progress (based on the same `sourceCriterion` strategy).
61+
62+
### `sourceCriterion`
63+
64+
SourceCriterion defines what criterion is used to group requests as originating from a common source.
65+
The precedence order is `ipStrategy`, then `requestHeaderName`, then `requestHost`.
66+
If none are set, the default is to use the `requestHost`.
67+
68+
#### `sourceCriterion.ipStrategy`
69+
70+
The `ipStrategy` option defines two parameters that sets how Traefik will determine the client IP: `depth`, and `excludedIPs`.
71+
72+
##### `ipStrategy.depth`
73+
74+
The `depth` option tells Traefik to use the `X-Forwarded-For` header and take the IP located at the `depth` position (starting from the right).
75+
76+
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP will be empty.
77+
- `depth` is ignored if its value is is lesser than or equal to 0.
78+
79+
!!! note "Example of Depth & X-Forwarded-For"
80+
81+
If `depth` was equal to 2, and the request `X-Forwarded-For` header was `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP would be `"10.0.0.1"` (at depth 4) but the IP used as the criterion would be `"12.0.0.1"` (`depth=2`).
82+
83+
| `X-Forwarded-For` | `depth` | clientIP |
84+
|-----------------------------------------|---------|--------------|
85+
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `1` | `"13.0.0.1"` |
86+
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `3` | `"11.0.0.1"` |
87+
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `5` | `""` |
88+
89+
##### `ipStrategy.excludedIPs`
90+
91+
`excludedIPs` tells Traefik to scan the `X-Forwarded-For` header and pick the first IP not in the list.
92+
93+
!!! important
94+
If `depth` is specified, `excludedIPs` is ignored.
95+
96+
!!! note "Example of ExcludedIPs & X-Forwarded-For"
97+
98+
| `X-Forwarded-For` | `excludedIPs` | clientIP |
99+
|-----------------------------------------|-----------------------|--------------|
100+
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"12.0.0.1,13.0.0.1"` | `"11.0.0.1"` |
101+
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
102+
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"10.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
103+
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
104+
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
105+
106+
```yaml tab="Docker"
107+
labels:
108+
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
109+
```
110+
111+
```yaml tab="Kubernetes"
112+
apiVersion: traefik.containo.us/v1alpha1
113+
kind: Middleware
114+
metadata:
115+
name: test-inflightreq
116+
spec:
117+
inFlightReq:
118+
sourceCriterion:
119+
ipStrategy:
120+
excludedIPs:
121+
- 127.0.0.1/32
122+
- 192.168.1.7
123+
```
124+
125+
```yaml tab="Rancher"
126+
labels:
127+
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
128+
```
129+
130+
```json tab="Marathon"
131+
"labels": {
132+
"traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7"
133+
}
134+
```
135+
136+
```toml tab="File (TOML)"
137+
[http.middlewares]
138+
[http.middlewares.test-inflightreq.inflightreq]
139+
[http.middlewares.test-inflightreq.inFlightReq.sourceCriterion.ipStrategy]
140+
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
141+
```
142+
143+
```yaml tab="File (YAML)"
144+
http:
145+
middlewares:
146+
test-inflightreq:
147+
inFlightReq:
148+
sourceCriterion:
149+
ipStrategy:
150+
excludedIPs:
151+
- "127.0.0.1/32"
152+
- "192.168.1.7"
153+
```
154+
155+
#### `sourceCriterion.requestHeaderName`
156+
157+
Requests having the same value for the given header are grouped as coming from the same source.
158+
159+
```yaml tab="Docker"
160+
labels:
161+
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
162+
```
163+
164+
```yaml tab="Kubernetes"
165+
apiVersion: traefik.containo.us/v1alpha1
166+
kind: Middleware
167+
metadata:
168+
name: test-inflightreq
169+
spec:
170+
inFlightReq:
171+
sourceCriterion:
172+
requestHeaderName: username
173+
```
174+
175+
```yaml tab="Rancher"
176+
labels:
177+
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
178+
```
179+
180+
```json tab="Marathon"
181+
"labels": {
182+
"traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername": "username"
183+
}
184+
```
185+
186+
```toml tab="File (TOML)"
187+
[http.middlewares]
188+
[http.middlewares.test-inflightreq.inflightreq]
189+
[http.middlewares.test-inflightreq.inFlightReq.sourceCriterion]
190+
requestHeaderName = "username"
191+
```
192+
193+
```yaml tab="File (YAML)"
194+
http:
195+
middlewares:
196+
test-inflightreq:
197+
inFlightReq:
198+
sourceCriterion:
199+
requestHeaderName: username
200+
```
201+
202+
#### `sourceCriterion.requestHost`
203+
204+
Whether to consider the request host as the source.
205+
206+
```yaml tab="Docker"
207+
labels:
208+
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
209+
```
210+
211+
```yaml tab="Kubernetes"
212+
apiVersion: traefik.containo.us/v1alpha1
213+
kind: Middleware
214+
metadata:
215+
name: test-inflightreq
216+
spec:
217+
inFlightReq:
218+
sourceCriterion:
219+
requestHost: true
220+
```
221+
222+
```yaml tab="Rancher"
223+
labels:
224+
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
225+
```
226+
227+
```json tab="Marathon"
228+
"labels": {
229+
"traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost": "true"
230+
}
231+
```
232+
233+
```toml tab="File (TOML)"
234+
[http.middlewares]
235+
[http.middlewares.test-inflightreq.inflightreq]
236+
[http.middlewares.test-inflightreq.inFlightReq.sourceCriterion]
237+
requestHost = true
238+
```
239+
240+
```yaml tab="File (YAML)"
241+
http:
242+
middlewares:
243+
test-inflightreq:
244+
inFlightReq:
245+
sourceCriterion:
246+
requestHost: true
247+
```

docs/content/middlewares/maxconnection.md

Lines changed: 0 additions & 71 deletions
This file was deleted.

docs/content/middlewares/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ and therefore this specification would be ignored even if present.
208208
| [ForwardAuth](forwardauth.md) | Authentication delegation | Security, Authentication |
209209
| [Headers](headers.md) | Add / Update headers | Security |
210210
| [IPWhiteList](ipwhitelist.md) | Limit the allowed client IPs | Security, Request lifecycle |
211-
| [MaxConnection](maxconnection.md) | Limit the number of simultaneous connections | Security, Request lifecycle |
211+
| [InFlightReq](inflightreq.md) | Limit the number of simultaneous connections | Security, Request lifecycle |
212212
| [PassTLSClientCert](passtlsclientcert.md) | Adding Client Certificates in a Header | Security |
213213
| [RateLimit](ratelimit.md) | Limit the call frequency | Security, Request lifecycle |
214214
| [RedirectScheme](redirectscheme.md) | Redirect easily the client elsewhere | Request lifecycle |

0 commit comments

Comments
 (0)