Skip to content

Commit c53d8dd

Browse files
authored
Merge pull request quarkusio#36128 from cescoffier/traffic-shaping
Add support for traffic shaping
2 parents b10a14f + 06724f7 commit c53d8dd

File tree

4 files changed

+148
-5
lines changed

4 files changed

+148
-5
lines changed

docs/src/main/asciidoc/http-reference.adoc

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ include::_attributes.adoc[]
1111
:sectnums:
1212
:sectnumlevels: 4
1313

14-
:numbered:
15-
:sectnums:
16-
:sectnumlevels: 4
17-
1814

1915
This document explains various HTTP features that you can use in Quarkus.
2016

@@ -394,6 +390,44 @@ It is important that you enable all origins only for the dev profile, allowing a
394390

395391
include::{generated-dir}/config/quarkus-vertx-http-config-group-server-limits-config.adoc[leveloffset=+1, opts=optional]
396392

393+
== Configure traffic shaping
394+
395+
Traffic shaping allows you to limit the bandwidth across all channels (i.e. connections), regardless of the number of open channels.
396+
This can be useful when you want to control the overall network traffic to prevent congestion or prioritize certain types of traffic.
397+
398+
To enable traffic shaping, add the following property in your application configuration:
399+
400+
401+
[source, properties]
402+
----
403+
quarkus.http.traffic-shaping.enabled=true # Required to enable traffic shaping
404+
----
405+
406+
The traffic shaping allows you to configure various parameters, such as write and read limitations (in bytes per second), check interval (the delay between two computations of the bandwidth), and maximum time to wait:
407+
408+
[source, properties]
409+
----
410+
quarkus.http.traffic-shaping.enabled=true # Required to enable traffic shaping
411+
quarkus.http.traffic-shaping.check-interval=30s
412+
quarkus.http.traffic-shaping.outbound-global-bandwidth=1M
413+
quarkus.http.traffic-shaping.inbound-global-bandwidth=1M
414+
quarkus.http.traffic-shaping.max-delay=10s
415+
----
416+
417+
The check interval represents the period at which the traffic is computed, and a higher interval may result in
418+
less precise traffic shaping.
419+
Despite 0 being accepted (no accounting), it is recommended to set a positive value for the check interval, even if it is high since the precision of the traffic shaping depends on the period where the traffic is computed.
420+
In this case, a suggested value is something close to 5 or 10 minutes.
421+
422+
The `outbound-global-bandwidth` and `inbound-global-bandwidth` parameters represent the maximum number of bytes per second for write and read operations, respectively.
423+
You shall also consider to have object size in read or write operations relatively adapted to the bandwidth you required.
424+
For instance having 10 MB objects for 10KB/s will lead to burst effect, while having 100 KB objects for 1 MB/s should be smoothly handle by the traffic shaping.
425+
426+
Additionally, you can set the maximum time to wait (`max-delay`), which specifies an upper bound for time shaping.
427+
By default, it is set to 15 seconds.
428+
It must be less than the HTTP timeout.
429+
When one of the threshold is reached, no write happens for that period of time.
430+
397431
== Configuring HTTP Access Logs
398432

399433
You can add HTTP request logging by configuring it in `application.properties`. There are two options for logging,

extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/HttpConfiguration.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,9 @@ public class HttpConfiguration {
229229
@ConfigItem
230230
public boolean recordRequestStartTime;
231231

232-
AccessLogConfig accessLog;
232+
public AccessLogConfig accessLog;
233+
234+
public TrafficShapingConfig trafficShaping;
233235

234236
/**
235237
* Configuration that allows setting the same site attributes for cookies.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package io.quarkus.vertx.http.runtime;
2+
3+
import java.time.Duration;
4+
import java.util.Optional;
5+
6+
import io.quarkus.runtime.annotations.ConfigGroup;
7+
import io.quarkus.runtime.annotations.ConfigItem;
8+
import io.quarkus.runtime.configuration.MemorySize;
9+
10+
/**
11+
* Configure the global traffic shaping functionality.
12+
* It allows you to limit the bandwidth across all channels, regardless of the number of open channels.
13+
* This can be useful when you want to control the overall network traffic to prevent congestion
14+
* or prioritize certain types of traffic.
15+
* <p>
16+
* The traffic shaping allows you to configure various parameters, such as write and read limitations (in bytes per
17+
* second), check interval (the delay between two computations of the bandwidth), and maximum time to wait.
18+
* The check interval represents the period at which the traffic is computed, and a higher interval may result in
19+
* less precise traffic shaping. It is recommended to set a positive value for the check interval, even if it is high,
20+
* to ensure traffic shaping without accounting. A suggested value is something close to 5 or 10 minutes.
21+
* <p>
22+
* The `outbound-global-bandwidth` and `inbound-global-bandwidth` parameters represent the maximum number of bytes per second
23+
* for write and read operations, respectively.
24+
* Additionally, you can set the maximum time to wait, which specifies an upper bound for time shaping.
25+
* By default, it is set to 15 seconds.
26+
*/
27+
@ConfigGroup
28+
public class TrafficShapingConfig {
29+
30+
/**
31+
* Enables the traffic shaping.
32+
*/
33+
@ConfigItem(defaultValue = "false")
34+
public boolean enabled;
35+
36+
/**
37+
* Set bandwidth limit in bytes per second for inbound connections.
38+
* If not set, no limits are applied.
39+
*/
40+
@ConfigItem
41+
public Optional<MemorySize> inboundGlobalBandwidth;
42+
43+
/**
44+
* Set bandwidth limit in bytes per second for outbound connections.
45+
* If not set, no limits are applied.
46+
*/
47+
@ConfigItem
48+
public Optional<MemorySize> outboundGlobalBandwidth;
49+
50+
/**
51+
* Set the maximum delay to wait in case of traffic excess.
52+
* Default is 15s. Must be less than the HTTP timeout.
53+
*/
54+
@ConfigItem
55+
public Optional<Duration> maxDelay;
56+
57+
/**
58+
* Set the delay between two computations of performances for channels.
59+
* If set to 0, no stats are computed.
60+
* Despite 0 is accepted (no accounting), it is recommended to set a positive value for the check interval,
61+
* even if it is high since the precision of the traffic shaping depends on the period where the traffic is computed.
62+
* In this case, a suggested value is something close to 5 or 10 minutes.
63+
* <p>
64+
* If not default, it defaults to 1s.
65+
*/
66+
@ConfigItem
67+
public Optional<Duration> checkInterval;
68+
69+
/**
70+
* Set the maximum global write size in bytes per second allowed in the buffer globally for all channels before write
71+
* are suspended.
72+
* The default value is 400 MB.
73+
*/
74+
@ConfigItem
75+
public Optional<MemorySize> peakOutboundGlobalBandwidth;
76+
77+
}

extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/options/HttpServerOptionsUtils.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
import io.vertx.core.net.JdkSSLEngineOptions;
3030
import io.vertx.core.net.KeyStoreOptions;
3131
import io.vertx.core.net.PemKeyCertOptions;
32+
import io.vertx.core.net.TrafficShapingOptions;
3233

34+
@SuppressWarnings("OptionalIsPresent")
3335
public class HttpServerOptionsUtils {
3436

3537
/**
@@ -276,6 +278,34 @@ public static void applyCommonOptions(HttpServerOptions httpServerOptions,
276278
}
277279

278280
httpServerOptions.setUseProxyProtocol(httpConfiguration.proxy.useProxyProtocol);
281+
configureTrafficShapingIfEnabled(httpServerOptions, httpConfiguration);
282+
}
283+
284+
private static void configureTrafficShapingIfEnabled(HttpServerOptions httpServerOptions,
285+
HttpConfiguration httpConfiguration) {
286+
if (httpConfiguration.trafficShaping.enabled) {
287+
TrafficShapingOptions options = new TrafficShapingOptions();
288+
if (httpConfiguration.trafficShaping.checkInterval.isPresent()) {
289+
options.setCheckIntervalForStats(httpConfiguration.trafficShaping.checkInterval.get().toSeconds());
290+
options.setCheckIntervalForStatsTimeUnit(TimeUnit.SECONDS);
291+
}
292+
if (httpConfiguration.trafficShaping.maxDelay.isPresent()) {
293+
options.setMaxDelayToWait(httpConfiguration.trafficShaping.maxDelay.get().toSeconds());
294+
options.setMaxDelayToWaitUnit(TimeUnit.SECONDS);
295+
}
296+
if (httpConfiguration.trafficShaping.inboundGlobalBandwidth.isPresent()) {
297+
options.setInboundGlobalBandwidth(httpConfiguration.trafficShaping.inboundGlobalBandwidth.get().asLongValue());
298+
}
299+
if (httpConfiguration.trafficShaping.outboundGlobalBandwidth.isPresent()) {
300+
options.setOutboundGlobalBandwidth(
301+
httpConfiguration.trafficShaping.outboundGlobalBandwidth.get().asLongValue());
302+
}
303+
if (httpConfiguration.trafficShaping.peakOutboundGlobalBandwidth.isPresent()) {
304+
options.setPeakOutboundGlobalBandwidth(
305+
httpConfiguration.trafficShaping.peakOutboundGlobalBandwidth.get().asLongValue());
306+
}
307+
httpServerOptions.setTrafficShapingOptions(options);
308+
}
279309
}
280310

281311
public static void applyCommonOptionsForManagementInterface(HttpServerOptions options,

0 commit comments

Comments
 (0)