Skip to content

Commit

Permalink
feat: save code
Browse files Browse the repository at this point in the history
  • Loading branch information
chuuuevi committed Jul 16, 2024
1 parent 1d84aea commit 9755cf3
Show file tree
Hide file tree
Showing 7 changed files with 279 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

```bash
docker build -t c100k .
docker run --rm -it --network=host c100k --http-port=22221 --server-type=vertx
docker run --rm -it --network=host c100k --http-port=22221 --server-type=jdk21
```

```bash
Expand Down
117 changes: 117 additions & 0 deletions docs/bm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@


# server is c6i.2xlarge, wrk is t3.xlarge

## vertx-server with virtual thread

```text
docker run --rm -it qyvlik/wrk -t 4 -c 128 -d 30s http://172.31.15.175:22221
Running 30s test @ http://172.31.15.175:22221
4 threads and 128 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.31ms 3.38ms 103.42ms 97.91%
Req/Sec 15.20k 2.50k 17.62k 90.25%
1817753 requests in 30.06s, 122.02MB read
Requests/sec: 60474.25
Transfer/sec: 4.06MB
```

## jdk21-server with virtual thread

```text
docker run --rm -it qyvlik/wrk -t 4 -c 128 -d 30s http://172.31.15.175:22221
Running 30s test @ http://172.31.15.175:22221
4 threads and 128 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.00ms 726.86us 18.86ms 94.45%
Req/Sec 15.65k 1.60k 18.13k 69.42%
1870264 requests in 30.05s, 146.26MB read
Requests/sec: 62238.05
Transfer/sec: 4.87MB
```

# server is r7iz.2xlarge, wrk is t3.xlarge

## jdk21-server with virtual thread

```text
docker run --rm -it qyvlik/wrk -t 4 -c 128 -d 30s http://172.31.15.175:22221
Running 30s test @ http://172.31.15.175:22221
4 threads and 128 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.96ms 3.02ms 210.76ms 99.20%
Req/Sec 16.44k 2.33k 18.55k 91.99%
1960191 requests in 30.03s, 152.23MB read
Requests/sec: 65278.12
Transfer/sec: 5.07MB
```

## vertx-server with virtual thread

```text
docker run --rm -it qyvlik/wrk -t 4 -c 128 -d 30s http://172.31.15.175:22221
Running 30s test @ http://172.31.15.175:22221
4 threads and 128 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.04ms 2.93ms 97.97ms 98.16%
Req/Sec 16.94k 2.02k 19.19k 89.83%
2025090 requests in 30.05s, 136.06MB read
Requests/sec: 67389.46
Transfer/sec: 4.53MB
```

# server is r7iz.2xlarge, wrk is c5.xlarge

## jdk21-server with virtual thread

```text
docker run --rm -it qyvlik/wrk -t 4 -c 128 -d 30s http://172.31.15.175:22221
Running 30s test @ http://172.31.15.175:22221
4 threads and 128 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 743.23us 311.82us 11.89ms 79.91%
Req/Sec 30.95k 1.03k 33.33k 80.08%
3695409 requests in 30.02s, 292.10MB read
Requests/sec: 123098.29
Transfer/sec: 9.73MB
```

```text
docker run --rm -it qyvlik/wrk -t 4 -c 256 -d 30s http://172.31.15.175:22221
Running 30s test @ http://172.31.15.175:22221
4 threads and 256 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.39ms 576.88us 16.50ms 75.75%
Req/Sec 23.93k 1.02k 32.84k 76.67%
2859455 requests in 30.08s, 223.61MB read
Socket errors: connect 0, read 308865, write 0, timeout 0
Requests/sec: 95057.99
Transfer/sec: 7.43MB
```

## vertx-server with virtual thread

```text
docker run --rm -it qyvlik/wrk -t 4 -c 128 -d 30s http://172.31.15.175:22221
Running 30s test @ http://172.31.15.175:22221
4 threads and 128 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.35ms 117.79us 15.17ms 93.81%
Req/Sec 23.70k 353.95 24.48k 80.83%
2829395 requests in 30.01s, 191.58MB read
Requests/sec: 94286.83
Transfer/sec: 6.38MB
```

```text
docker run --rm -it qyvlik/wrk -t 4 -c 256 -d 30s http://172.31.15.175:22221
Running 30s test @ http://172.31.15.175:22221
4 threads and 256 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.69ms 131.46us 14.83ms 88.43%
Req/Sec 23.82k 317.41 25.98k 71.75%
2843861 requests in 30.03s, 192.56MB read
Requests/sec: 94716.42
Transfer/sec: 6.41MB
```

6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@
<version>2.0.13</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>


</dependencies>
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/chuuuevi/github/io/server/C100kServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ public static void main(String[] args) throws IOException, ParseException {
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse(options, args);
int port = cmd.hasOption("http-port") ? Integer.parseInt(cmd.getOptionValue("http-port")) : 22222;
String type = cmd.hasOption("server-type") ? cmd.getOptionValue("server-type") : "vertx";
String type = cmd.hasOption("server-type") ? cmd.getOptionValue("server-type") : "jdk21";

Counter counter = new Counter();

if (type .equals("jdk21")) {
new JDK21Server(port, counter);
new JDK21Server(port, counter, true);
} else {
new VertxServer(port, counter);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,10 @@ public long read() throws ExecutionException, InterruptedException {
this.disruptor.publishEvent(this::readTranslator, future);
return future.get();
}

public CompletableFuture<Long> readAsync() {
CompletableFuture<Long> future = new CompletableFuture<>();
this.disruptor.publishEvent(this::readTranslator, future);
return future;
}
}
73 changes: 52 additions & 21 deletions src/main/java/chuuuevi/github/io/server/server/JDK21Server.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,74 @@
package chuuuevi.github.io.server.server;

import chuuuevi.github.io.server.disruptor.Counter;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpServer;
import org.apache.commons.cli.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class JDK21Server {

private static final Logger log = LoggerFactory.getLogger(JDK21Server.class);

private HttpServer server;
private final Counter counter;
private final Executor executor;

public JDK21Server(int port, Counter counter) throws IOException {
public JDK21Server(int port, Counter counter, boolean asyncHandle) throws IOException {
this.counter = counter;
this.executor = Executors.newVirtualThreadPerTaskExecutor();
this.server = HttpServer.create(new InetSocketAddress(port), 0);
this.server.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
server.createContext("/").setHandler(exchange -> {
// System.out.println("request "+ exchange.getRequestURI());

counter.dealt(1);
Long number = null;
try {
number = counter.read();
} catch (Exception e) {

}
byte[] respText = (number == null ? "-1" : number.toString()).getBytes(StandardCharsets.UTF_8);

exchange.sendResponseHeaders(200, respText.length);
try (var os = exchange.getResponseBody()) {
os.write(respText);
}
});
this.server.setExecutor(this.executor);
if (asyncHandle) {
server.createContext("/").setHandler(this::handleAsync);
} else {
server.createContext("/").setHandler(this::handleSync);
}

this.server.start();
log.info("jdk21-server startup at {}", port);
log.info("jdk21-server startup at {}, async={}", port, asyncHandle);
}

private void handleSync(HttpExchange exchange) throws IOException {

counter.dealt(1);
Long number = null;
try {
number = counter.read();
} catch (Exception e) {

}
byte[] respText = (number == null ? "-1" : number.toString()).getBytes(StandardCharsets.UTF_8);

exchange.sendResponseHeaders(200, respText.length);
try (var os = exchange.getResponseBody()) {
os.write(respText);
}
}


private void handleAsync(HttpExchange exchange) throws IOException {
counter.dealt(1);

counter.readAsync().thenAcceptAsync(
(number) -> {
byte[] respText = (number == null ? "-1" : number.toString()).getBytes(StandardCharsets.UTF_8);
try {
exchange.sendResponseHeaders(200, respText.length);
try (var os = exchange.getResponseBody()) {
os.write(respText);
}
} catch (IOException e) {

}
},
this.executor
);
}
}
95 changes: 95 additions & 0 deletions src/test/java/chuuuevi/github/io/server/disruptor/CounterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package chuuuevi.github.io.server.disruptor;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import static org.junit.jupiter.api.Assertions.*;

class CounterTest {

private static final Logger log = LoggerFactory.getLogger(CounterTest.class);

@Test
public void testSingleProducer() throws ExecutionException, InterruptedException {
Counter counter = new Counter();

final int total = 15_0000;
int iter = total;

Instant begin = Instant.now();
while (iter-- > 0) {
counter.dealt(1);
counter.read();
}
Instant end = Instant.now();

Duration cost = Duration.between(begin, end);

log.info("counter total={}, cost={} ", total, cost);
}

@Test
public void testVT() throws ExecutionException, InterruptedException {
Counter counter = new Counter();

final int total = 15_0000;
int iter = total;

Executor executor = Executors.newVirtualThreadPerTaskExecutor();

Instant begin = Instant.now();
while (iter-- > 0) {

executor.execute(()->{
counter.dealt(1);
try {
counter.read();
} catch (Exception e) {

}
});
}

counter.read();

Instant end = Instant.now();

Duration cost = Duration.between(begin, end);

log.info("counter total={}, cost={} ", total, cost);
}


@Test
public void testVT2() throws ExecutionException, InterruptedException {
Counter counter = new Counter();

final int total = 15_0000;
int iter = total;

Executor executor = Executors.newVirtualThreadPerTaskExecutor();

Instant begin = Instant.now();
while (iter-- > 0) {

executor.execute(()->{
counter.dealt(1);
});
}

counter.read();

Instant end = Instant.now();

Duration cost = Duration.between(begin, end);

log.info("counter total={}, cost={} ", total, cost);
}
}

0 comments on commit 9755cf3

Please sign in to comment.