Ensure a sufficient virtual threads pool (#37197)

Closes #37162

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
Alexander Schwartz 2025-02-10 16:28:24 +01:00 committed by GitHub
parent b7b84d75d1
commit 822eb4471d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 3 deletions

View File

@ -15,7 +15,7 @@ See the https://www.keycloak.org/server/caching[Configuring distributed caches]
= Virtual Threads enabled for Infinispan and JGroups thread pools
Starting from this release, {project_name} automatically enables the virtual thread pool support in both the embedded Infinispan and JGroups when running on OpenJDK 21.
Starting from this release, {project_name} automatically enables the virtual thread pool support in both the embedded Infinispan and JGroups when running on OpenJDK 21 for environments with at least 2 CPU cores available.
This removes the need to configure the JGroups thread pool, the need to align the JGroups thread pool with the HTTP worker thread pool, and reduces the overall memory footprint.
= OpenTelemetry Tracing supported

View File

@ -17,7 +17,7 @@ For a configuration where this is applied, visit <@links.ha id="deploy-keycloak-
// remove this paragraph once OpenJDK 17 is no longer supported on the server side.
// https://github.com/keycloak/keycloak/issues/31101
JGroups communications, which is used in single-site setups for the communication between {project_name} nodes, benefits from the use of virtual threads which are available in OpenJDK 21.
JGroups communications, which is used in single-site setups for the communication between {project_name} nodes, benefits from the use of virtual threads which are available in OpenJDK 21 when at least two cores are available for {project_name}.
This reduces the memory usage and removes the need to configure thread pool sizes.
Therefore, the use of OpenJDK 21 is recommended.

View File

@ -53,21 +53,43 @@ public class KeycloakMain implements QuarkusApplication {
private static final String INFINISPAN_VIRTUAL_THREADS_PROP = "org.infinispan.threads.virtual";
public static final int MIN_VT_POOL_SIZE = 2;
static {
// enable Infinispan and JGroups virtual threads by default
if (System.getProperty(INFINISPAN_VIRTUAL_THREADS_PROP) == null) {
if (System.getProperty(INFINISPAN_VIRTUAL_THREADS_PROP) == null && getParallelism() >= MIN_VT_POOL_SIZE) {
System.setProperty(INFINISPAN_VIRTUAL_THREADS_PROP, "true");
}
}
public static void main(String[] args) {
ensureForkJoinPoolThreadFactoryHasBeenSetToQuarkus();
ensureVirtualThreadsParallelism();
System.setProperty("kc.version", Version.VERSION);
main(args, new Picocli());
}
private static void ensureVirtualThreadsParallelism() {
if (Boolean.parseBoolean(System.getProperty(INFINISPAN_VIRTUAL_THREADS_PROP))) {
if (getParallelism() < MIN_VT_POOL_SIZE) {
throw new RuntimeException("To be able to use Infinispan/JGroups virtual threads, you need to set the Java system property jdk.virtualThreadScheduler.parallelism to at least " + MIN_VT_POOL_SIZE);
}
}
}
private static int getParallelism() {
int parallelism;
String parallelismValue = System.getProperty("jdk.virtualThreadScheduler.parallelism");
if (parallelismValue != null) {
parallelism = Integer.parseInt(parallelismValue);
} else {
parallelism = Runtime.getRuntime().availableProcessors();
}
return parallelism;
}
public static void main(String[] args, Picocli picocli) {
List<String> cliArgs = null;
try {