Skip to content

Commit 3d9ee77

Browse files
committed
Introduce Mode enum (NON_VIRTUAL_NETTY, REACTIVE, VIRTUAL_NETTY, NETTY_SCHEDULER), add mockless mode, and simplify benchmark runner configuration
1 parent a29d91a commit 3d9ee77

5 files changed

Lines changed: 276 additions & 204 deletions

File tree

benchmark-runner/README.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,9 @@ All configuration is via environment variables:
6464
|----------|---------|-------------|
6565
| `SERVER_PORT` | 8081 | Server port |
6666
| `SERVER_THREADS` | 2 | Number of event loop threads |
67-
| `SERVER_REACTIVE` | false | Use reactive handler with Reactor |
68-
| `SERVER_USE_CUSTOM_SCHEDULER` | false | Use custom Netty scheduler |
67+
| `SERVER_MODE` | NON_VIRTUAL_NETTY | Server mode: NON_VIRTUAL_NETTY, REACTIVE, VIRTUAL_NETTY, NETTY_SCHEDULER |
68+
| `SERVER_MOCKLESS` | false | Skip mock server; do Jackson work inline |
6969
| `SERVER_IO` | epoll | I/O type: epoll, nio, or io_uring |
70-
| `SERVER_NO_TIMEOUT` | false | Disable HTTP client timeout |
7170
| `SERVER_TASKSET` | 2,3 | CPU affinity (e.g., "2-5") |
7271
| `SERVER_JVM_ARGS` | | Additional JVM arguments |
7372
| `SERVER_POLLER_MODE` | 3 | jdk.pollerMode value: 1, 2, or 3 |
@@ -153,17 +152,16 @@ perf stat uses `PROFILING_DELAY_SECONDS` and `PROFILING_DURATION_SECONDS`.
153152

154153
## Example Runs
155154

156-
### Basic comparison: custom vs default scheduler
155+
### Basic comparison: modes
157156

158157
```bash
159-
# With custom scheduler
158+
# Custom scheduler mode
160159
JAVA_HOME=/path/to/jdk \
161-
SERVER_USE_CUSTOM_SCHEDULER=true \
160+
SERVER_MODE=NETTY_SCHEDULER \
162161
./run-benchmark.sh
163162

164-
# With default scheduler
163+
# Default split topology
165164
JAVA_HOME=/path/to/jdk \
166-
SERVER_USE_CUSTOM_SCHEDULER=false \
167165
./run-benchmark.sh
168166
```
169167

@@ -175,7 +173,7 @@ MOCK_TASKSET="0" \
175173
SERVER_TASKSET="1-4" \
176174
LOAD_GEN_TASKSET="5-7" \
177175
SERVER_THREADS=4 \
178-
SERVER_USE_CUSTOM_SCHEDULER=true \
176+
SERVER_MODE=NETTY_SCHEDULER \
179177
./run-benchmark.sh
180178
```
181179

@@ -186,7 +184,7 @@ JAVA_HOME=/path/to/jdk \
186184
ENABLE_PROFILER=true \
187185
ASYNC_PROFILER_PATH=/path/to/async-profiler \
188186
PROFILER_EVENT=cpu \
189-
SERVER_USE_CUSTOM_SCHEDULER=true \
187+
SERVER_MODE=NETTY_SCHEDULER \
190188
WARMUP_DURATION=15s \
191189
TOTAL_DURATION=45s \
192190
./run-benchmark.sh
@@ -198,7 +196,7 @@ TOTAL_DURATION=45s \
198196
JAVA_HOME=/path/to/jdk \
199197
ENABLE_JFR=true \
200198
JFR_EVENTS=NettyRunIo,VirtualThreadTaskRuns \
201-
SERVER_USE_CUSTOM_SCHEDULER=true \
199+
SERVER_MODE=NETTY_SCHEDULER \
202200
./run-benchmark.sh
203201
```
204202

@@ -213,6 +211,15 @@ WARMUP_DURATION=15s \
213211
./run-benchmark.sh
214212
```
215213

214+
### Netty on ForkJoinPool mode
215+
216+
```bash
217+
JAVA_HOME=/path/to/jdk \
218+
SERVER_MODE=VIRTUAL_NETTY \
219+
SERVER_THREADS=2 \
220+
./run-benchmark.sh
221+
```
222+
216223
### With pidstat monitoring
217224

218225
```bash
@@ -260,7 +267,7 @@ java -cp benchmark-runner/target/benchmark-runner.jar \
260267
8080 1 # port, thinkTimeMs (threads defaults to available processors)
261268
```
262269

263-
### Handoff Server (with custom scheduler)
270+
### Handoff Server (custom scheduler mode)
264271

265272
```bash
266273
java \
@@ -275,11 +282,11 @@ java \
275282
--port 8081 \
276283
--mock-url http://localhost:8080/fruits \
277284
--threads 2 \
278-
--use-custom-scheduler true \
285+
--mode netty_scheduler \
279286
--io epoll
280287
```
281288

282-
### Handoff Server (with default scheduler)
289+
### Handoff Server (default split topology)
283290

284291
```bash
285292
java \
@@ -292,6 +299,5 @@ java \
292299
--port 8081 \
293300
--mock-url http://localhost:8080/fruits \
294301
--threads 2 \
295-
--use-custom-scheduler false \
296302
--io epoll
297303
```

benchmark-runner/scripts/run-benchmark.sh

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ MOCK_TASKSET="${MOCK_TASKSET:-4,5}" # CPUs for mock server
3030
# Handoff server configuration
3131
SERVER_PORT="${SERVER_PORT:-8081}"
3232
SERVER_THREADS="${SERVER_THREADS:-2}"
33-
SERVER_USE_CUSTOM_SCHEDULER="${SERVER_USE_CUSTOM_SCHEDULER:-false}"
3433
SERVER_IO="${SERVER_IO:-epoll}"
3534
SERVER_TASKSET="${SERVER_TASKSET:-2,3}" # CPUs for handoff server
3635
SERVER_JVM_ARGS="${SERVER_JVM_ARGS:-}"
37-
SERVER_POLLER_MODE="${SERVER_POLLER_MODE:-3}" # jdk.pollerMode value (1, 2, or 3)
36+
SERVER_POLLER_MODE="${SERVER_POLLER_MODE:-}" # jdk.pollerMode value (1, 2, or 3); empty = JVM default, NETTY_SCHEDULER defaults to 3
3837
SERVER_FJ_PARALLELISM="${SERVER_FJ_PARALLELISM:-}" # ForkJoinPool parallelism (empty = JVM default)
39-
SERVER_NO_TIMEOUT="${SERVER_NO_TIMEOUT:-false}" # Disable HTTP client timeout
40-
SERVER_REACTIVE="${SERVER_REACTIVE:-false}" # Use reactive handler with Project Reactor
38+
SERVER_FJ_AFFINITY="${SERVER_FJ_AFFINITY:-false}" # ForkJoinPool virtual thread scheduler affinity
39+
SERVER_MODE="${SERVER_MODE:-NON_VIRTUAL_NETTY}" # Server mode: NON_VIRTUAL_NETTY, REACTIVE, VIRTUAL_NETTY
40+
SERVER_MOCKLESS="${SERVER_MOCKLESS:-false}" # Skip mock server; do Jackson work inline
4141

4242
# Load generator configuration
4343
LOAD_GEN_TASKSET="${LOAD_GEN_TASKSET:-0,1}" # CPUs for load generator
@@ -57,6 +57,7 @@ PROFILING_DURATION_SECONDS="${PROFILING_DURATION_SECONDS:-10}"
5757
# Profiling configuration
5858
ENABLE_PROFILER="${ENABLE_PROFILER:-false}"
5959
PROFILER_EVENT="${PROFILER_EVENT:-cpu}"
60+
PROFILER_FORMAT="${PROFILER_FORMAT:-flamegraph}" # Output format: flamegraph, collapsed, jfr
6061
PROFILER_OUTPUT="${PROFILER_OUTPUT:-profile.html}"
6162
ASYNC_PROFILER_PATH="${ASYNC_PROFILER_PATH:-}" # Path to async-profiler
6263

@@ -382,15 +383,27 @@ start_handoff_server() {
382383
jvm_args="$jvm_args -XX:-DoJVMTIVirtualThreadTransitions"
383384
jvm_args="$jvm_args -Djdk.trackAllThreads=false"
384385

385-
if [[ "$SERVER_USE_CUSTOM_SCHEDULER" == "true" ]]; then
386-
jvm_args="$jvm_args -Djdk.virtualThreadScheduler.implClass=io.netty.loom.NettyScheduler"
387-
jvm_args="$jvm_args -Djdk.pollerMode=$SERVER_POLLER_MODE"
386+
# Mode-specific JVM args
387+
local poller_mode="$SERVER_POLLER_MODE"
388+
case "$SERVER_MODE" in
389+
NETTY_SCHEDULER)
390+
jvm_args="$jvm_args -Djdk.virtualThreadScheduler.implClass=io.netty.loom.NettyScheduler"
391+
# Default pollerMode to 3 for custom scheduler if not explicitly set
392+
poller_mode="${poller_mode:-3}"
393+
;;
394+
esac
395+
396+
# Apply pollerMode if set (explicitly or via mode default)
397+
if [[ -n "$poller_mode" ]]; then
398+
jvm_args="$jvm_args -Djdk.pollerMode=$poller_mode"
388399
fi
389400

390401
if [[ -n "$SERVER_FJ_PARALLELISM" ]]; then
391402
jvm_args="$jvm_args -Djdk.virtualThreadScheduler.parallelism=$SERVER_FJ_PARALLELISM"
392403
fi
393404

405+
jvm_args="$jvm_args -Djdk.virtualThreadScheduler.affinity=$SERVER_FJ_AFFINITY"
406+
394407
# Add debug non-safepoints if profiling is enabled
395408
if [[ "$ENABLE_PROFILER" == "true" ]]; then
396409
jvm_args="$jvm_args -XX:+UnlockDiagnosticVMOptions"
@@ -402,15 +415,19 @@ start_handoff_server() {
402415
jvm_args="$jvm_args $SERVER_JVM_ARGS"
403416
fi
404417

418+
local mockless_flag=""
419+
if [[ "$SERVER_MOCKLESS" == "true" ]]; then
420+
mockless_flag="--mockless"
421+
fi
422+
405423
local cmd="$taskset_cmd $java_cmd $JAVA_OPTS $jvm_args -cp $RUNNER_JAR \
406424
io.netty.loom.benchmark.runner.HandoffHttpServer \
407425
--port $SERVER_PORT \
408426
--mock-url http://localhost:$MOCK_PORT/fruits \
409427
--threads $SERVER_THREADS \
410-
--use-custom-scheduler $SERVER_USE_CUSTOM_SCHEDULER \
411428
--io $SERVER_IO \
412-
--no-timeout $SERVER_NO_TIMEOUT \
413-
--reactive $SERVER_REACTIVE \
429+
--mode $SERVER_MODE \
430+
$mockless_flag \
414431
--silent"
415432

416433
log "Handoff server command: $cmd"
@@ -467,7 +484,8 @@ start_profiler() {
467484

468485
(
469486
sleep "$PROFILING_DELAY_SECONDS"
470-
"$asprof" --threads -e "$PROFILER_EVENT" -o flamegraph -d "$PROFILING_DURATION_SECONDS" -f "$output_file" "$SERVER_PID"
487+
# --record-cpu
488+
"$asprof" --threads -e "$PROFILER_EVENT" -o "$PROFILER_FORMAT" -d "$PROFILING_DURATION_SECONDS" -f "$output_file" "$SERVER_PID"
471489
) &
472490
PROFILER_PID=$!
473491

@@ -700,12 +718,12 @@ print_config() {
700718
log "Handoff Server:"
701719
log " Port: $SERVER_PORT"
702720
log " Threads: $SERVER_THREADS"
703-
log " Reactive: $SERVER_REACTIVE"
704-
log " Custom Sched: $SERVER_USE_CUSTOM_SCHEDULER"
721+
log " Mode: $SERVER_MODE"
722+
log " Mockless: $SERVER_MOCKLESS"
705723
log " I/O Type: $SERVER_IO"
706-
log " No Timeout: $SERVER_NO_TIMEOUT"
707724
log " Poller Mode: $SERVER_POLLER_MODE"
708725
log " FJ Parallelism: ${SERVER_FJ_PARALLELISM:-<default>}"
726+
log " FJ Affinity: $SERVER_FJ_AFFINITY"
709727
log " CPU Affinity: ${SERVER_TASKSET:-<none>}"
710728
log " Extra JVM Args: ${SERVER_JVM_ARGS:-<none>}"
711729
log ""
@@ -786,14 +804,14 @@ Mock Server:
786804
Handoff Server:
787805
SERVER_PORT Server port (default: 8081)
788806
SERVER_THREADS Number of event loop threads (default: 2)
789-
SERVER_REACTIVE Use reactive handler with Reactor (default: false)
790-
SERVER_USE_CUSTOM_SCHEDULER Use custom Netty scheduler (default: false)
807+
SERVER_MODE Server mode: NON_VIRTUAL_NETTY, REACTIVE, VIRTUAL_NETTY, NETTY_SCHEDULER (default: NON_VIRTUAL_NETTY)
808+
SERVER_MOCKLESS Skip mock server; do Jackson work inline (default: false)
791809
SERVER_IO I/O type: epoll, nio, or io_uring (default: epoll)
792-
SERVER_NO_TIMEOUT Disable HTTP client timeout (default: false)
793810
SERVER_TASKSET CPU affinity range (default: "2,3")
794811
SERVER_JVM_ARGS Additional JVM arguments
795812
SERVER_POLLER_MODE jdk.pollerMode value: 1, 2, or 3 (default: 3)
796813
SERVER_FJ_PARALLELISM ForkJoinPool parallelism (empty = JVM default)
814+
SERVER_FJ_AFFINITY ForkJoinPool scheduler affinity (default: false)
797815
798816
Load Generator:
799817
LOAD_GEN_CONNECTIONS Number of connections (default: 100)
@@ -847,8 +865,8 @@ General:
847865
848866
Examples:
849867
850-
# Basic run with custom scheduler
851-
JAVA_HOME=/path/to/jdk SERVER_USE_CUSTOM_SCHEDULER=true ./run-benchmark.sh
868+
# Custom scheduler mode
869+
JAVA_HOME=/path/to/jdk SERVER_MODE=NETTY_SCHEDULER ./run-benchmark.sh
852870
853871
# Run with CPU pinning and profiling
854872
JAVA_HOME=/path/to/jdk \
@@ -866,12 +884,24 @@ Examples:
866884
WARMUP_DURATION=15s \
867885
./run-benchmark.sh
868886
869-
# Reactive handler test
887+
# Reactive mode
888+
JAVA_HOME=/path/to/jdk \
889+
SERVER_MODE=REACTIVE \
890+
SERVER_THREADS=2 \
891+
./run-benchmark.sh
892+
893+
# Netty on ForkJoinPool mode
870894
JAVA_HOME=/path/to/jdk \
871-
SERVER_REACTIVE=true \
895+
SERVER_MODE=VIRTUAL_NETTY \
872896
SERVER_THREADS=2 \
873897
./run-benchmark.sh
874898
899+
# Mockless mode (no mock server, inline Jackson work)
900+
JAVA_HOME=/path/to/jdk \
901+
SERVER_MODE=VIRTUAL_NETTY \
902+
SERVER_MOCKLESS=true \
903+
SERVER_THREADS=2 \
904+
./run-benchmark.sh
875905
EOF
876906
exit 0
877907
;;
@@ -898,7 +928,11 @@ EOF
898928
build_jars
899929

900930
# Start servers
901-
start_mock_server
931+
if [[ "$SERVER_MOCKLESS" != "true" ]]; then
932+
start_mock_server
933+
else
934+
log "Mockless mode: skipping mock server"
935+
fi
902936
start_handoff_server
903937

904938
# Run warmup (no profiling/pidstat)

0 commit comments

Comments
 (0)