Skip to content

Commit 598729b

Browse files
committed
README
1 parent 797ed9c commit 598729b

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

README.md

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
## FusionAuth HTTP client and server ![semver 2.0.0 compliant](http://img.shields.io/badge/semver-2.0.0-brightgreen.svg?style=flat-square) [![test](https://github.com/FusionAuth/java-http/actions/workflows/test.yml/badge.svg)](https://github.com/FusionAuth/java-http/actions/workflows/test.yml)
22

3-
**NOTE:** This project is in progress.
3+
**NOTE:** This project is in progress. Version `0.3.0` is production ready, version `0.4.0` which will likely become `1.0.0` is still in development.
44

55
The goal of this project is to build a full-featured HTTP server and client in plain Java without the use of any libraries. The client and server will use Project Loom virtual threads and blocking I/O so that the Java VM will handle all the context switching between virtual threads as they block on I/O.
66

77
For more information about Project Loom and virtual threads, here is a good article to read: https://blogs.oracle.com/javamagazine/post/java-virtual-threads
88

9+
## Project Goals
10+
11+
- Very fast
12+
- Easy to make a simple web server like you can in Node.js
13+
- No dependencies
14+
- To not boil the ocean. This is a purpose built HTTP server that probably won't do everything.
15+
916
## Installation
1017

1118
To add this library to your project, you can include this dependency in your Maven POM:
@@ -14,20 +21,20 @@ To add this library to your project, you can include this dependency in your Mav
1421
<dependency>
1522
<groupId>io.fusionauth</groupId>
1623
<artifactId>java-http</artifactId>
17-
<version>0.4.0-RC.4</version>
24+
<version>0.4.0-RC.7</version>
1825
</dependency>
1926
```
2027

2128
If you are using Gradle, you can add this to your build file:
2229

2330
```groovy
24-
implementation 'io.fusionauth:java-http:0.4.0-RC.4'
31+
implementation 'io.fusionauth:java-http:0.4.0-RC.7'
2532
```
2633

2734
If you are using Savant, you can add this to your build file:
2835

2936
```groovy
30-
dependency(id: "io.fusionauth:java-http:0.4.0-RC.4")
37+
dependency(id: "io.fusionauth:java-http:0.4.0-RC.7")
3138
```
3239

3340
## Examples Usages:
@@ -158,17 +165,53 @@ Then you can open `https://example.org` in a browser or call it using an HTTP cl
158165

159166
## Performance
160167

161-
A key component for this project is to have awesome performance. Here are some basic metrics using the FusionAuth load test suite against a simple application using the Prime Framework MVC. The controller does nothing except return a simple 200. Here are some simple comparisons between `Tomcat`, `Netty`, and `java-http`.
168+
A key purpose for this project is obtain screaming performance. Here are some basic metrics using the FusionAuth load test suite against a boilerplate request handler. The request handler simply returns a `200`. Here are some simple comparisons between `apache-tomcat`, `Netty`, and `java-http`.
169+
170+
The load test configuration is set to `100` clients with `100,000` requests each per worker. This means the entire test will execute `10,000,000` requests. The HTTP client is [Restify](https://github.com/inversoft/restify) which is a FusionAuth library that uses `HttpURLConnection` under the hoods. This REST client is used because it is considerably faster than the native Java REST client. In a real life example, depending upon your application, this performance may not matter. For the purposes of a load test, we have attempted to remove as many limitations to pushing the server as hard as we can.
162171

163-
The load test configuration is set to 10 clients with 500,000 requests each. The client is Restify which is a FusionAuth library that uses `HttpURLConnection` under the hoods. All the servers were HTTP so that TLS would not introduce any additional latency.
172+
All the servers were HTTP so that TLS would not introduce any additional latency.
164173

165174
Here are the current test results:
166175

167-
| Server | RPS | Failures per second |
168-
|-------------|--------|---------------------|
169-
| `java-http` | 63,216 | 0 |
170-
| `Tomcat` | 51,351 | 0.103 |
171-
| `Netty` | 540 | 1.818 |
176+
| Server | Avg requests per second | Failures per second | Avg latency in ms | Normalized Performance (%) |
177+
|----------------|---------------------------|-----------------------|-------------------------|----------------------------|
178+
| java-http | 101,317 | 0 | 0.350 | 100% |
179+
| Apache Tomcat | 83,463 | 0 | 0.702 | 82.3% |
180+
| Netty | ? | ? | ? | |
181+
| OkHttp | ? | ? | ? | |
182+
| JDK HttpServer | ? | ? | ? | |
183+
184+
Note the JDK HTTP Server is `com.sun.net.httpserver.HttpServer`. I don't know that anyone would use this in production, the JDK has not yet made a version of this using a public API. It is included here for reference only.
185+
186+
Load test last performed May 30, 2025. Using the [fusionauth-load-test](https://github.com/fusionauth/fusionauth-load-tests) library.
187+
188+
### Running load tests
189+
190+
Start the HTTP server to test.
191+
192+
#### java-http
193+
194+
Start the HTTP server. Run the following commands from the `java-http` repo.
195+
196+
```bash
197+
cd load-tests/self
198+
sb clean start
199+
```
200+
201+
#### Apache Tomcat
202+
203+
Start the HTTP server. Run the following commands from the `java-http` repo.
204+
```bash
205+
cd load-tests/tomcat
206+
sb clean start
207+
```
208+
209+
Once you have the server started you wish to test, start the load test. Run the following commands from the `fusionauth-load-tests` repo.
210+
211+
```bash
212+
sb clean int
213+
./load-test.sh HTTP.json
214+
```
172215

173216
Netty and Tomcat both seem to suffer from buffering and connection issues at very high scale. Regardless of the configuration, both servers always begins to fail with connection timeout problems at scale. `java-http` does not have these issues because of the way it handles connections via the selector. Connections don't back up and client connection pools can always be re-used with Keep-Alive.
174217

0 commit comments

Comments
 (0)