Skip to content

Commit

Permalink
New doc describing the concurrency limit support in webserver (helido…
Browse files Browse the repository at this point in the history
…n-io#9725)

* Initial version of doc.
* Moved concurrency limit over to docs. Create new folder for Webserver.
* Clarifies default queueing behavior in note.

Signed-off-by: Santiago Pericas-Geertsen <[email protected]>
  • Loading branch information
spericas authored Feb 5, 2025
1 parent b22ef14 commit 9820388
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 25 deletions.
4 changes: 2 additions & 2 deletions docs/src/main/asciidoc/about/doc_overview.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2018, 2024 Oracle and/or its affiliates.
Copyright (c) 2018, 2025 Oracle and/or its affiliates.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -112,7 +112,7 @@ xref:{rootdir}/mp/guides/overview.adoc[MP Guides]
.Advanced SE Features
[icon=hotel_class]
--
xref:{rootdir}/se/webserver.adoc[Helidon WebServer]
xref:{rootdir}/se/webserver/webserver.adoc[Helidon WebServer]
xref:{rootdir}/se/metrics/metrics.adoc[Helidon Metrics]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Still, there might be cases where you wish to change configuration options from
For details on the following options please see:
* xref:../../se/webserver.adoc#_configuration_options[WebServer Configuration]
* xref:../../se/webserver/webserver.adoc#_configuration_options[WebServer Configuration]
* xref:../../config/io_helidon_common_socket_SocketOptions.adoc[WebServer Socket Configuration]
== Summary of Tuning Options
Expand Down
4 changes: 2 additions & 2 deletions docs/src/main/asciidoc/mp/grpc/client.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2019, 2024 Oracle and/or its affiliates.
Copyright (c) 2019, 2025 Oracle and/or its affiliates.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -114,7 +114,7 @@ grpc:
TLS in the gRPC MP client section is configured in the same way as in other Helidon
components such as the webserver. For more information see
xref:{rootdir}/se/webserver.adoc#_configuring_tls[Configuring TLS].
xref:{rootdir}/se/webserver/webserver.adoc#_configuring_tls[Configuring TLS].
Given that TLS is enabled by default in gRPC, it must be explicitly turned off by
setting the `enabled` flag to `false` when connecting to an unsecure endpoint.
Expand Down
6 changes: 3 additions & 3 deletions docs/src/main/asciidoc/se/cors.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2022, 2024 Oracle and/or its affiliates.
Copyright (c) 2022, 2025 Oracle and/or its affiliates.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -139,7 +139,7 @@ The link:{helidon-github-examples-url}/quickstarts/helidon-quickstart-se[Helidon
lets you change the greeting by sending a `PUT` request to the `/greet/greeting` resource.
This example, based on the QuickStart greeting app, uses the low-level `CrossOriginConfig` API and
the `CorsSupport` API to influence the xref:{rootdir}/se/webserver.adoc#routing[routing],
the `CorsSupport` API to influence the xref:{rootdir}/se/webserver/webserver.adoc#routing[routing],
thereby determining how that resource is shared. (If desired, you can use <<Configuration, configuration>> instead
of the low-level API.)
Expand Down Expand Up @@ -251,7 +251,7 @@ For a complete example, see {helidon-github-examples-url}/cors[Helidon SE CORS E
include::{rootdir}/includes/cors.adoc[tag=cors-and-requested-uri-intro]
You can configure how the Helidon server handles these headers as described in the documentation for
xref:{rootdir}/se/webserver.adoc#_requested_uri_discovery[requested URI discovery].
xref:{rootdir}/se/webserver/webserver.adoc#_requested_uri_discovery[requested URI discovery].
include::{rootdir}/includes/cors.adoc[tag=cors-and-requested-uri-wrapup]
Expand Down
6 changes: 3 additions & 3 deletions docs/src/main/asciidoc/se/guides/upgrade_3x.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2022, 2024 Oracle and/or its affiliates.
Copyright (c) 2022, 2025 Oracle and/or its affiliates.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -37,7 +37,7 @@ Please follow the instructions in xref:{rootdir}/about/prerequisites.adoc[Prereq
Handling routes based on the protocol version is now possible by registering specific routes
on routing builder.
For further information check xref:../webserver.adoc[WebServer Documentation]
For further information check xref:../webserver/webserver.adoc[WebServer Documentation]
== Http/2 Support
Expand Down Expand Up @@ -82,7 +82,7 @@ server:
max-upgrade-content-length: 16384
----
For further information check xref:../webserver.adoc[WebServer Documentation]
For further information check xref:../webserver/webserver.adoc[WebServer Documentation]
== WebSocket
Expand Down
4 changes: 2 additions & 2 deletions docs/src/main/asciidoc/se/guides/upgrade_4x.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ If you want full control using the API, you still have that option.
For more information see:
* xref:../observability.adoc[Observability feature support]
* xref:../webserver.adoc#_media_types_support[Media types support]
* xref:../webserver/webserver.adoc#_media_types_support[Media types support]
== Routing Configuration
Expand Down Expand Up @@ -176,7 +176,7 @@ It receives `HttpRules` object with routes description.
WARNING: These changes make Helidon 4 incompatible with previous versions.
Learn more about `HttpService` and `Routing` at xref:../webserver.adoc[Helidon SE WebServer]
Learn more about `HttpService` and `Routing` at xref:../webserver/webserver.adoc[Helidon SE WebServer]
=== Other Significant Changes
Expand Down
4 changes: 2 additions & 2 deletions docs/src/main/asciidoc/se/introduction.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2019, 2024 Oracle and/or its affiliates.
Copyright (c) 2019, 2025 Oracle and/or its affiliates.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -133,7 +133,7 @@ HTTP client that handles responses to the HTTP requests.
//WebServer
[CARD]
.WebServer
[icon=settings_ethernet,link=webserver.adoc]
[icon=settings_ethernet,link=webserver/webserver.adoc]
--
A programmatic HTTP API that uses virtual threads to handle nearly unlimited concurrent requests without blocking a platform thread or starving other requests.
// Each request runs in its own dedicated thread, so it is free to perform blocking operations in a simple synchronous way without blocking a platform thread or starving other requests.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2018, 2024 Oracle and/or its affiliates.
Copyright (c) 2018, 2025 Oracle and/or its affiliates.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -25,7 +25,7 @@ include::{rootdir}/includes/se.adoc[]
== WebServer
To integrate xref:../webserver.adoc[web server], add the following dependency to your project's pom.xml file:
To integrate xref:../webserver/webserver.adoc[web server], add the following dependency to your project's pom.xml file:
[source,xml]
.Maven Dependency
Expand Down
209 changes: 209 additions & 0 deletions docs/src/main/asciidoc/se/webserver/concurrency-limits.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2025 Oracle and/or its affiliates.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

///////////////////////////////////////////////////////////////////////////////
= Concurrency Limits
:description: Helidon SE Concurrency Limits
:feature-name: Concurrency Limits
:microprofile-bundle: false
:keywords: helidon, se, performance, concurrency, limits
:rootdir: {docdir}/../..
include::{rootdir}/includes/se.adoc[]
== Introduction
With the introduction of virtual threads, Helidon is able to create a new
thread per request with the only limit being the available memory on the system.
In some situations, this scenario is not ideal as it can increase concurrency
beyond the capabilities of some other components in the system, such as a database,
a network link, etc.
In those cases, and when scaling of those components is not feasible or simply not desirable,
it may be beneficial
to limit the number of concurrent requests accepted by the Helidon webserver in
order to improve the overall experience. When doing so, it should also be possible
to establish rules for those requests that cannot be serviced immediately,
as well as how to grow or shrink the number of _permits_ available in the system.
== Setting Concurrency Limits
Helidon now includes support for two independent concurrency limit strategies:
fixed and AIMD (Arithmetic Increase Multiplicative Decrease) as well as an SPI
to provide alternative `LimitProvider` implementations. These
concurrency strategies are configured _as a feature_ for each network socket in the
webserver. As always, if configured directly as a webserver feature, it would
apply to the _default_ socket only.
The following example uses a fixed concurrency strategy to limit the number
of concurrent requests to 1000, a queue of 200 requests to accommodate
potential request bursts and a queue timeout of 1 second:
[source,yaml]
----
server:
features:
limits:
concurrency-limit:
fixed:
permits: 1000
queue-length: 200
queue-timeout: PT1S
----
With this configuration, after all 1000 permits are consumed, subsequent requests
will be queued, if possible, and any request that sits in the queue for more than
1 second will be rejected.
Instead of fixing the number of permits to a given value, the AIMD strategy
allows the set of permits to grow arithmetically and shrink multiplicatively
as needed, based on the actual time that it takes to process requests. AIMD
can dynamically adjust the number of available permits to ensure a certain
_quality of service_, possibly for a subset of all the requests received.
It is generally preferred to serve a subset of clients efficiently than
all clients inefficiently, and this type of tradeoff can be defined using
an AIMD strategy. For example,
[source,yaml]
----
server:
features:
limits:
concurrency-limit:
aimd:
min-limit: 100
max-limit: 1000
initial-limit: 500
timeout: "PT0.5S"
backoff-ratio: 0.75
----
With this configuration, the initial number of permits starts at 500 and
can vary between 100 and 1000. The timeout set at 500 milliseconds is used
to determine how to limit concurrency: if a request completes under this
limit, then the number of permits can increase by one up to the maximum;
if a request fails or if it completes over this limit, then the number
of permits shrinks using the backoff ratio (by 75% in our example) up
to the minimum.
AIMD also supports queueing and queueing timeouts, so if the maximum size
is reached, it is still possible to accept (enqueue) a request as long
as it is processed within the queueing timeout period. Here is a variation
of the example above, but with a queue of size 300 and a queue timeout of
1 second:
[source,yaml]
----
server:
features:
limits:
concurrency-limit:
aimd:
min-limit: 100
max-limit: 1000
initial-limit: 500
timeout: "PT0.5S"
backoff-ratio: 0.75
queue-length: 300
queue-timeout: PT1S
----
NOTE: Queues can be useful to accommodate short bursts of
requests that would otherwise be rejected when the number of permits
is exhausted. Queueing is disabled by default in both fixed and
AIMD strategies, so `queue-length` must be set to a positive number
to enable this feature.
Neither of the two strategies shown above enables
queues by default.
For more information about configuring these Concurrency Limit
strategies see:
- xref:{rootdir}/config/io_helidon_common_concurrency_limits_FixedLimit.adoc[FixedLimit]
- xref:{rootdir}/config/io_helidon_common_concurrency_limits_AimdLimit.adoc[AimdLimit]
== Metrics
The Concurrency Limit module also has built-in support for metrics in order
to monitor the chosen strategy. These metrics are disabled by default,
but can be enabled as follows:
[source,yaml]
----
server:
features:
limits:
concurrency-limit:
fixed:
permits: 1000
queue-length: 200
queue-timeout: PT1S
enable-metrics: true # turn on metrics!
----
The following tables describe the metrics that are available for each of the
strategies described above. A metric tag `socketName=<name-of-socket>` is used to
group metrics that correspond to a particular socket; for simplicity this metric tag
is _omitted_ for the default socket. All metrics provided by the Concurrency Limit
module are in **vendor** scope.
.Fixed
|===
|Name |Description
|`fixed_queue_length`
|Gauge that returns the number of requests waiting on the queue at a certain time
|`fixed_rejected_requests`
|Gauge that returns the number of requests that have been rejected so far
|`fixed_rtt`
|Distribution summary of round-trip times, excluding any time waiting in the queue
|`fixed_queue_wait_time`
|Distribution summary of queue wait times
|`fixed_concurrent_requests`
|Gauge that returns the number of requests being processed at a certain time
|===
.AIMD
|===
|Name |Description
|`aimd_queue_length`
|Gauge that returns the number of requests waiting on the queue at a certain time
|`aimd_rejected_requests`
|Gauge that returns the number of requests that have been rejected so far
|`aimd_rtt`
|Distribution summary of round-trip times, excluding any time waiting in the queue
|`aimd_queue_wait_time`
|Distribution summary of queue wait times
|`aimd_concurrent_requests`
|Gauge that returns the number of requests being processed at a certain time
|`aimd_limit`
|Gauge that returns the actual limit at a certain time
|===
For more information regarding metrics support in Helidon and the dependencies that are
required for metrics to work, see xref:{metrics-page}[Helidon Metrics].
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
:description: Helidon WebServer Introduction
:keywords: helidon, java, webserver, tls
:feature-name: WebServer
:rootdir: {docdir}/..
:rootdir: {docdir}/../..
:requested-uri-discovery-inc: {rootdir}/includes/server/requested-uri-discovery.adoc
include::{rootdir}/includes/se.adoc[]
Expand Down Expand Up @@ -526,22 +526,22 @@ first.
|<<Access Log, Access Log>>
|1000
|xref:tracing.adoc[Tracing]
|xref:{rootdir}/se/tracing.adoc[Tracing]
|900
|xref:cors.adoc[CORS]
|xref:{rootdir}/se/cors.adoc[CORS]
|850
|xref:security/introduction.adoc[Security]
|xref:{rootdir}/se/security/introduction.adoc[Security]
|800
|Routing (all handlers and filters)
|100
|xref:openapi/openapi.adoc[OpenAPI]
|xref:{rootdir}/se/openapi/openapi.adoc[OpenAPI]
|90
|xref:observability.adoc[Observability]
|xref:{rootdir}/se/observability.adoc[Observability]
|80
|===
Expand Down
Loading

0 comments on commit 9820388

Please sign in to comment.