Skip to content

Commit fe1810b

Browse files
authored
Performance improvements to vertx-web-kotlin-dsljson (#10281)
- Refactored core verticles and introduced ServerVerticle for improved request handling - Enhanced database repositories with optimized query patterns - Streamlined handlers to reduce overhead - Updated PeriodicResolver logic and added centralized Properties configuration - Removed unused profiling scripts and configuration files - Temporarily disabled fortunes endpoint in benchmark configuration - Updated Gradle build configuration and dependencies Verify was called to ensure operability.
1 parent 13ff46a commit fe1810b

39 files changed

+1165
-605
lines changed

frameworks/Kotlin/vertx-web-kotlin-dsljson/README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ http://localhost:8080/query?queries=
3131

3232
http://localhost:8080/update?queries=
3333

34-
### FORTUNES
3534

36-
http://localhost:8080/fortunes
35+
Testing:
36+
37+
```shell
38+
../../../tfb \
39+
--mode benchmark \
40+
--test vertx-web-kotlin-dsljson \
41+
--type json
42+
```

frameworks/Kotlin/vertx-web-kotlin-dsljson/benchmark_config.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
"postgresql": {
2525
"db_url": "/db",
2626
"query_url": "/queries?queries=",
27-
"fortune_url": "/fortunes",
2827
"update_url": "/updates?queries=",
2928
"port": 8080,
3029
"approach": "Realistic",
Lines changed: 90 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,116 @@
1-
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
21
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
32

43
plugins {
5-
kotlin("jvm") version "1.9.22"
6-
kotlin("kapt") version "1.9.22"
4+
alias(libs.plugins.kotlin.jvm)
5+
alias(libs.plugins.kotlin.kapt)
6+
alias(libs.plugins.shadow)
77
application
8-
id("com.github.johnrengelman.shadow") version "7.1.2"
98
}
109

1110
group = "com.example"
1211
version = "1.0.0-SNAPSHOT"
1312

14-
repositories {
15-
mavenCentral()
16-
}
17-
1813
java {
1914
toolchain {
20-
languageVersion.set(JavaLanguageVersion.of(21))
15+
languageVersion.set(JavaLanguageVersion.of(25))
2116
}
2217
}
2318

2419
kotlin {
2520
compilerOptions {
26-
jvmTarget = JvmTarget.JVM_21
21+
jvmTarget = JvmTarget.JVM_25
22+
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_3)
23+
languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_3)
24+
freeCompilerArgs.addAll(listOf(
25+
"-Xjvm-default=all",
26+
"-Xlambdas=indy",
27+
"-Xjdk-release=25"
28+
))
2729
}
28-
jvmToolchain(21)
30+
jvmToolchain(25)
2931
}
3032

31-
val mainClassName = "com.example.starter.App"
32-
33-
val vertxVersion = "4.5.9"
34-
val nettyVersion = "4.1.112.Final"
35-
val scramVersion = "2.1"
36-
val dslJsonVersion = "2.0.2"
37-
val htmlFlowVersion = "4.6"
38-
val log4jVersion = "2.23.1"
39-
4033
application {
41-
mainClass = mainClassName
34+
mainClass = "com.example.starter.AppKt"
4235
}
4336

4437
dependencies {
45-
listOfNotNull(
46-
// Kotlin
47-
kotlin("stdlib-jdk8"),
48-
kotlin("reflect"),
49-
50-
// Vertx
51-
platform("io.vertx:vertx-stack-depchain:$vertxVersion"),
52-
"io.vertx:vertx-core",
53-
"io.vertx:vertx-web",
54-
"io.vertx:vertx-pg-client",
55-
"io.vertx:vertx-lang-kotlin",
56-
"io.vertx:vertx-lang-kotlin-coroutines",
57-
58-
// Netty
59-
"io.netty:netty-transport-native-epoll:$nettyVersion:linux-x86_64",
60-
61-
// Postgres
62-
"com.ongres.scram:client:$scramVersion",
63-
64-
// dsljson
65-
"com.dslplatform:dsl-json:$dslJsonVersion",
66-
67-
// HtmlFlow
68-
"com.github.xmlet:htmlflow:$htmlFlowVersion",
69-
70-
// Logging
71-
"org.apache.logging.log4j:log4j-core:$log4jVersion",
72-
"org.apache.logging.log4j:log4j-api:$log4jVersion",
73-
"org.apache.logging.log4j:log4j-api-kotlin:1.4.0",
74-
"com.lmax:disruptor:4.0.0",
75-
).map { implementation(it) }
76-
77-
listOf(
78-
"com.dslplatform:dsl-json:$dslJsonVersion",
79-
"org.apache.logging.log4j:log4j-core:$log4jVersion",
80-
).map { kapt(it) }
38+
// Kotlin
39+
implementation(libs.kotlin.stdlib)
40+
implementation(libs.kotlin.reflect)
41+
42+
// Vert.x
43+
implementation(platform(libs.vertx.bom))
44+
implementation(libs.vertx.core)
45+
implementation(libs.vertx.web)
46+
implementation(libs.vertx.pg.client)
47+
implementation(libs.vertx.lang.kotlin)
48+
implementation(libs.vertx.lang.kotlin.coroutines)
49+
implementation(libs.vertx.micrometer)
50+
51+
// Micrometer
52+
implementation(libs.micrometer.registry.prometheus)
53+
54+
// Netty
55+
implementation(platform(libs.netty.bom))
56+
resolvePlatformSpecificNettyDependencies(libs.versions.netty.get())
57+
.forEach { implementation(it) }
58+
59+
// DSL-JSON
60+
implementation(libs.dsl.json)
61+
kapt(libs.dsl.json)
62+
63+
// Log4j
64+
implementation(libs.log4j.core)
65+
implementation(libs.log4j.api)
66+
implementation(libs.log4j.api.kotlin)
67+
implementation(libs.disruptor)
8168
}
8269

83-
tasks.withType<ShadowJar> {
84-
archiveClassifier = "fat"
85-
mergeServiceFiles()
70+
tasks {
71+
register<JavaExec>("server") {
72+
dependsOn(this@tasks.classes)
73+
74+
mainClass.set(application.mainClass.get())
75+
classpath = sourceSets.main.get().runtimeClasspath
76+
77+
jvmArgs = listOf(
78+
"-server",
79+
"--enable-native-access=ALL-UNNAMED",
80+
"--add-opens=java.base/java.lang=ALL-UNNAMED",
81+
"--sun-misc-unsafe-memory-access=allow",
82+
"-Xms2G",
83+
"-Xmx2G",
84+
"-XX:+AlwaysPreTouch",
85+
"-XX:+UseParallelGC",
86+
"-XX:InitialCodeCacheSize=512m",
87+
"-XX:ReservedCodeCacheSize=512m",
88+
"-XX:MaxInlineLevel=20",
89+
"-XX:+UseNUMA",
90+
"-XX:-UseCodeCacheFlushing",
91+
"-XX:AutoBoxCacheMax=10001",
92+
"-XX:+UseCompactObjectHeaders",
93+
"-XX:+UnlockDiagnosticVMOptions",
94+
"-XX:+DebugNonSafepoints",
95+
"-Djava.net.preferIPv4Stack=true",
96+
"-Dvertx.disableMetrics=true",
97+
"-Dvertx.disableWebsockets=true",
98+
"-Dvertx.disableContextTimings=true",
99+
"-Dvertx.cacheImmutableHttpResponseHeaders=true",
100+
"-Dvertx.internCommonHttpRequestHeadersToLowerCase=true",
101+
"-Dvertx.disableHttpHeadersValidation=true",
102+
"-Dio.netty.noUnsafe=false",
103+
"-Dio.netty.buffer.checkBounds=false",
104+
"-Dio.netty.buffer.checkAccessible=false",
105+
"-Dio.netty.leakDetection.level=disabled",
106+
"-Dio.netty.iouring.ringSize=4096",
107+
"-Dio.netty.iouring.cqSize=8192",
108+
"-Dtfb.type=basic",
109+
)
110+
}
111+
112+
shadowJar {
113+
archiveClassifier = "fat"
114+
mergeServiceFiles()
115+
}
86116
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
plugins {
2+
`kotlin-dsl`
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
enum class SystemType {
2+
LINUX_X86_64,
3+
LINUX_AMD64,
4+
LINUX_AARCH64,
5+
OSX_X86_64,
6+
OSX_AARCH64,
7+
WINDOWS_AMD64,
8+
WINDOWS_AARCH64,
9+
UNKNOWN,
10+
}
11+
12+
data class SystemInfo(
13+
val type: SystemType,
14+
val os: OperatingSystem,
15+
) {
16+
data class OperatingSystem(
17+
val name: String,
18+
val arch: String,
19+
)
20+
}
21+
22+
val CURRENT_SYSTEM_INFO by lazy {
23+
val os = System.getProperty("os.name").lowercase()
24+
val arch = System.getProperty("os.arch").lowercase()
25+
val type = when {
26+
os.startsWith("linux") && arch == "x86_64" -> SystemType.LINUX_X86_64
27+
os.startsWith("linux") && arch == "amd64" -> SystemType.LINUX_AMD64
28+
os.startsWith("linux") && arch == "aarch64" -> SystemType.LINUX_AARCH64
29+
os.startsWith("mac") && arch == "x86_64" -> SystemType.OSX_X86_64
30+
os.startsWith("mac") && arch == "aarch64" -> SystemType.OSX_AARCH64
31+
os.startsWith("windows") && arch == "amd64" -> SystemType.WINDOWS_AMD64
32+
os.startsWith("windows") && arch == "aarch64" -> SystemType.WINDOWS_AARCH64
33+
else -> SystemType.UNKNOWN
34+
}
35+
36+
SystemInfo(
37+
type = type,
38+
os = SystemInfo.OperatingSystem(
39+
name = os,
40+
arch = arch,
41+
)
42+
)
43+
}
44+
45+
fun resolvePlatformSpecificNettyDependencies(version: String) = when (CURRENT_SYSTEM_INFO.type) {
46+
SystemType.LINUX_X86_64,
47+
SystemType.LINUX_AMD64 -> arrayOf(
48+
"io.netty:netty-transport-native-io_uring:$version:linux-x86_64",
49+
)
50+
SystemType.LINUX_AARCH64 -> arrayOf(
51+
"io.netty:netty-transport-native-io_uring:$version:linux-aarch_64",
52+
)
53+
SystemType.OSX_AARCH64 -> arrayOf(
54+
"io.netty:netty-transport-native-kqueue:$version:osx-aarch_64",
55+
"io.netty:netty-resolver-dns-native-macos:$version:osx-aarch_64",
56+
)
57+
else -> throw IllegalStateException("Unsupported system: $CURRENT_SYSTEM_INFO")
58+
}

frameworks/Kotlin/vertx-web-kotlin-dsljson/configuration/scripts/server.sh

100644100755
Lines changed: 72 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,92 @@
11
#!/bin/bash
22

3-
JVM_OPTS="-server \
3+
set -euo pipefail
4+
5+
if [ -f /proc/cpuinfo ]; then
6+
CPU_COUNT=$(grep --count ^processor /proc/cpuinfo)
7+
else
8+
CPU_COUNT=$(sysctl -n hw.ncpu 2>/dev/null || echo 1)
9+
fi
10+
11+
JAR_PATH="./build/libs/vertx-web-kotlin-dsljson-benchmark-1.0.0-SNAPSHOT-fat.jar"
12+
PG_DOCKER_PATH="../../../toolset/databases/postgres"
13+
14+
HAS_DB=false
15+
while [[ $# -gt 0 ]]; do
16+
case $1 in
17+
-db)
18+
HAS_DB=true
19+
;;
20+
esac
21+
shift
22+
done
23+
24+
if [ "$HAS_DB" = true ]; then
25+
docker image inspect tfb-postgres >/dev/null 2>&1 || \
26+
docker build -f "$PG_DOCKER_PATH/postgres.dockerfile" -t tfb-postgres "$PG_DOCKER_PATH"
27+
28+
# ensure no old container blocks name reuse
29+
docker rm -f tfb-postgres >/dev/null 2>&1 || true
30+
31+
docker run --rm --name tfb-postgres -p 5432:5432 -d tfb-postgres
32+
33+
until PGPASSWORD=benchmarkdbpass psql -h "0.0.0.0" -U benchmarkdbuser -d hello_world -c '\dt' > /dev/null 2>&1; do
34+
sleep 1
35+
done
36+
fi
37+
38+
cleanup() {
39+
echo "Caught termination signal. Cleaning up..."
40+
if [ -n "${JAVA_PID:-}" ]; then
41+
kill -SIGTERM "$JAVA_PID" 2>/dev/null || true
42+
wait "$JAVA_PID" 2>/dev/null || true
43+
fi
44+
45+
if [ "$HAS_DB" = true ]; then
46+
echo "Stopping postgres container..."
47+
docker stop tfb-postgres >/dev/null 2>&1 || true
48+
docker rm -f tfb-postgres >/dev/null 2>&1 || true
49+
fi
50+
}
51+
52+
trap cleanup SIGINT SIGTERM EXIT
53+
54+
java \
55+
-server \
56+
--enable-native-access=ALL-UNNAMED \
57+
--add-opens=java.base/java.lang=ALL-UNNAMED \
458
-Xms2G \
559
-Xmx2G \
660
-XX:+AlwaysPreTouch \
7-
-XX:+UseParallelGC \
8-
-XX:+PreserveFramePointer \
61+
-XX:+UseZGC \
62+
-XX:+ZUncommit \
63+
-XX:+DisableExplicitGC \
64+
-XX:+UseLargePages \
65+
-XX:+UseStringDeduplication \
966
-XX:+EnableDynamicAgentLoading \
1067
-XX:InitialCodeCacheSize=512m \
1168
-XX:ReservedCodeCacheSize=512m \
1269
-XX:MaxInlineLevel=20 \
1370
-XX:+UseNUMA \
14-
-Djava.lang.Integer.IntegerCache.high=10000 \
71+
-XX:-UseCodeCacheFlushing \
72+
-XX:AutoBoxCacheMax=10001 \
73+
-Djava.net.preferIPv4Stack=true \
1574
-Dvertx.disableMetrics=true \
16-
-Dvertx.disableH2c=true \
75+
-Dvertx.disableDnsResolver=true \
1776
-Dvertx.disableWebsockets=true \
18-
-Dvertx.flashPolicyHandler=false \
19-
-Dvertx.threadChecks=false \
2077
-Dvertx.disableContextTimings=true \
21-
-Dvertx.disableTCCL=true \
78+
-Dvertx.cacheImmutableHttpResponseHeaders=true \
79+
-Dvertx.internCommonHttpRequestHeadersToLowerCase=true \
2280
-Dvertx.disableHttpHeadersValidation=true \
23-
-Dvertx.eventLoopPoolSize=$((`grep --count ^processor /proc/cpuinfo`)) \
24-
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \
81+
-Dio.netty.noUnsafe=false \
2582
-Dio.netty.buffer.checkBounds=false \
2683
-Dio.netty.buffer.checkAccessible=false \
27-
-Dtfb.hasDB=false"
28-
29-
JAR_PATH="./build/libs/vertx-web-kotlin-dsljson-benchmark-1.0.0-SNAPSHOT-fat.jar"
30-
31-
cleanup() {
32-
echo "Caught SIGINT signal. Stopping the Java program..."
33-
if [ ! -z "$JAVA_PID" ]; then
34-
kill -SIGTERM "$JAVA_PID"
35-
wait "$JAVA_PID"
36-
fi
37-
exit 0
38-
}
39-
40-
trap cleanup SIGINT
84+
-Dio.netty.recycler.maxCapacity.default=0 \
85+
-Dio.netty.maxDirectMemory=0 \
86+
"-Dtfb.hasDB=$HAS_DB" \
87+
"-Dtfb.pgHostOverride=0.0.0.0" \
88+
-jar "$JAR_PATH" &
4189

42-
java $JVM_OPTS -jar $JAR_PATH &
4390
JAVA_PID=$!
4491

4592
echo "Server PID: $JAVA_PID"

0 commit comments

Comments
 (0)