Skip to content

Benchmarks for JDK HTTP Server running on Java 21 with Virtual Threads

License

Notifications You must be signed in to change notification settings

abelsromero/java-httpserver-vthreads

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Overview

The code and experiments shown in this repository are intended to demonstrate the capabilities of a simple, minimal Java web server application built atop the following JDK primitives:

Experiments were conducted in AWS cloud on modest c5.2xlarge EC2 instances with 8 vCPU and 16 GB RAM.

Environment

  • c5.2xlarge EC2 instances
  • Amazon Linux AMI 2.0.20231219 x86_64 ECS HVM GP2 ami-0d63309a12899f79d
  • OpenJDK 21.0.1
  • wrk HTTP benchmarking tool

Launch instance:

aws ec2 run-instances --image-id ami-0d63309a12899f79d ...

Download OpenJDK:

curl -s "https://download.java.net/java/GA/jdk21.0.1/415e3f918a1f4062a0074a2794853d0d/12/GPL/openjdk-21.0.1_linux-x64_bin.tar.gz" --output openjdk-21.0.1_linux-x64_bin.tar.gz
tar xvf openjdk-21.0.1_linux-x64_bin.tar.gz

Download and build wrk

sudo yum install git
sudo yum install "Development Tools"
git clone https://github.com/wg/wrk.git
cd wrk
make

Compile and Build

Compile source code with a javac command in the project directory.

javac -d mods/ src/httpsrv/*.java src/module-info.java

Create a custom, modular run-time image with a jlink command. JAVA_HOME refers to the OpenJDK installation directory.

jlink --module-path $JAVA_HOME/jmods:mods --add-modules httpsrv --output httpsrvimg

The contents of the resulting httpsrvimg are 57 MB.

$ du -h httpsrvimg/
364K	httpsrvimg/lib/security
25M	httpsrvimg/lib/server
56M	httpsrvimg/lib
4.0K	httpsrvimg/conf/sdp
12K	httpsrvimg/conf/security/policy/limited
8.0K	httpsrvimg/conf/security/policy/unlimited
24K	httpsrvimg/conf/security/policy
92K	httpsrvimg/conf/security
104K	httpsrvimg/conf
4.0K	httpsrvimg/include/linux
196K	httpsrvimg/include
48K	httpsrvimg/bin
116K	httpsrvimg/legal/java.base
0	httpsrvimg/legal/java.net.http
0	httpsrvimg/legal/jdk.httpserver
116K	httpsrvimg/legal
57M	httpsrvimg/

Start-up Time

The Hello Server writes a "ready" message to standard output after launch. This serves as a timing signal that indicates the conclusion of the JVM and application start-up process.

During each timing cycle, the profile.sh shell script measures

  1. System time prior to start
  2. System time after "ready" message received in stdin
  3. System time after GET / 200 OK response received

The difference between [1] and [2] is the start-up time and the difference between [2] and [3] is the time-to-response.

The profile.sh shell script measures these differences across 10 launches and prints the averages.

Start-up is 0.101 seconds on average.

Time-to-response is 0.179 seconds on average.

$ ./profile.sh 
0.116000, 0.191000, 200
0.097000, 0.185000, 200
0.096000, 0.175000, 200
0.108000, 0.189000, 200
0.097000, 0.170000, 200
0.098000, 0.178000, 200
0.097000, 0.170000, 200
0.108000, 0.183000, 200
0.102000, 0.178000, 200
0.098000, 0.172000, 200
---
0.101700, 0.179100

Hello Server

Hello is a simple application that starts a JDK HTTP server.

It responds to every HTTP request with a "hello world" plain-text response.

It uses a virtual-thread-per-task executor.

./httpsrvimg/bin/java -Dsun.net.httpserver.nodelay=true -m httpsrv/httpsrv.Hello

In the benchmark setting, two EC2 instances were used. One instance ran the Hello server and the other instance ran wrk.

+---------+                +---------+
|         |                |         |
|   wrk   +--------------->|  Hello  |
|         |                |         |
+---------+                +---------+

The following parameters were used for the wrk benchmark below:

  • 100 concurrent connections (-c)
  • 60 second duration (-d)
  • 8 threads (-t)

The resulting request rate for the execution below was 117,448 requests per second with an average latency of 844 microseconds.

$ ./wrk --latency -d 60s -c 100 -t 8 http:https://10.39.197.177:8080/
Running 1m test @ http:https://10.39.197.177:8080/
  8 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   844.44us    1.64ms 203.40ms   99.91%
    Req/Sec    14.78k     6.84k   24.85k    51.03%
  Latency Distribution
     50%  627.00us
     75%    0.94ms
     90%    1.71ms
     99%    2.04ms
  7058584 requests in 1.00m, 585.65MB read
Requests/sec: 117448.07
Transfer/sec:      9.74MB

Gateway Server

Gateway is a simple application that starts a JDK HTTP server.

It forwards every HTTP request to a separately deployed Hello server via the JDK HTTP client. Similarly, the Hello server response is forwarded back to the Gateway client.

It uses a virtual-thread-per-task executor.

./httpsrvimg/bin/java -Dsun.net.httpserver.nodelay=true -m httpsrv/httpsrv.Gateway http:https://10.39.197.199:8080/ 

In the benchmark setting, three EC2 instances were used. One instance ran the Gateway server, another ran the Hello server, and the last instance ran wrk.

+---------+                +-----------+                 +---------+
|         |                |           |                 |         |
|   wrk   +--------------->|  Gateway  +---------------->|  Hello  |
|         |                |           |                 |         |
+---------+                +-----------+                 +---------+
  • 100 concurrent connections (-c)
  • 60 second duration (-d)
  • 8 threads (-t)

The resulting request rate for the execution below was 53,485 requests per second with an average latency of 1.82 milliseconds.

$ ./wrk --latency -d 60s -c 100 -t 8 http:https://10.39.197.177:8080/
Running 1m test @ http:https://10.39.197.177:8080/
  8 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.82ms    1.99ms 203.11ms   99.03%
    Req/Sec     6.72k   397.07     8.32k    81.67%
  Latency Distribution
     50%    1.68ms
     75%    2.04ms
     90%    2.50ms
     99%    3.80ms
  3209334 requests in 1.00m, 266.28MB read
Requests/sec:  53485.25
Transfer/sec:      4.44MB

About

Benchmarks for JDK HTTP Server running on Java 21 with Virtual Threads

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 72.0%
  • Shell 28.0%