diff --git a/frameworks/Java/aio-socket/.dockerignore b/frameworks/Java/aio-socket/.dockerignore
new file mode 100644
index 00000000000..cba5dfe3c3b
--- /dev/null
+++ b/frameworks/Java/aio-socket/.dockerignore
@@ -0,0 +1,19 @@
+.github
+.git
+.DS_Store
+docs
+kubernetes
+node_modules
+/.svelte-kit
+/package
+.env
+.env.*
+vite.config.js.timestamp-*
+vite.config.ts.timestamp-*
+__pycache__
+.env
+_old
+uploads
+.ipynb_checkpoints
+**/*.db
+_test
\ No newline at end of file
diff --git a/frameworks/Java/aio-socket/.gitignore b/frameworks/Java/aio-socket/.gitignore
new file mode 100644
index 00000000000..2f089945614
--- /dev/null
+++ b/frameworks/Java/aio-socket/.gitignore
@@ -0,0 +1,3 @@
+/target/
+logs
+.settings
\ No newline at end of file
diff --git a/frameworks/Java/aio-socket/README.md b/frameworks/Java/aio-socket/README.md
new file mode 100644
index 00000000000..118b271982c
--- /dev/null
+++ b/frameworks/Java/aio-socket/README.md
@@ -0,0 +1,77 @@
+# t-io Benchmarking Test
+
+This is the tio-server portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+## Controller
+
+These implementations use the tio-server's controller.
+
+### Plaintext Test
+
+* [Plaintext test source](src/main/java/com/litongjava/tio/http/server/controller/IndexController.java)
+
+### JSON Serialization Test
+
+* [JSON test source](src/main/java/com/litongjava/tio/http/server/controller/IndexController.java)
+
+
+## Versions
+3.7.3.v20231218-RELEASE (https://gitee.com/litongjava/t-io)
+
+## Test URLs
+
+All implementations use the same URLs.
+
+### Plaintext Test
+
+ http://localhost:8080/plaintext
+
+### JSON Encoding Test
+
+ http://localhost:8080/json
+
+
+
+ ## Hot to run
+ ### install mysql 8
+ - 1.please instal mysql 8.0.32,example cmd
+ ```
+ docker run --restart=always -d --name mysql_8 --hostname mysql \
+-p 3306:3306 \
+-e 'MYSQL_ROOT_PASSWORD=robot_123456#' -e 'MYSQL_ROOT_HOST=%' -e 'MYSQL_DATABASE=hello_world' \
+mysql/mysql-server:8.0.32 \
+--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --lower_case_table_names=1
+ ```
+ - 2.create database schema hello_world
+ - 3.create tablle,[example](sql/hello_world.sql)
+ - 4.import data
+
+ ### docker
+ ```
+ docker build -t tio-server-benchmark -f tio-server.dockerfile .
+```
+The run is to specify the mysql database
+```
+docker run --rm -p 8080:8080 \
+-e JDBC_URL="jdbc:mysql://192.168.3.9/hello_world" \
+-e JDBC_USER="root" \
+-e JDBC_PSWD="robot_123456#" \
+tio-server-benchmark
+```
+
+### windows
+
+-windows
+```
+D:\java\jdk1.8.0_121\bin\java -jar target\tio-server-benchmark-1.0.jar --JDBC_URL=jdbc:mysql://192.168.3.9/hello_world?useSSL=false --JDBC_USER=root --JDBC_PSWD=robot_123456#
+```
+or
+```
+set JDBC_URL=jdbc:mysql://192.168.3.9/hello_world
+set jdbc.user=root
+set JDBC_PSWD=robot_123456#
+D:\java\jdk1.8.0_121\bin\java -jar target\tio-server-benchmark-1.0.jar
+```
+
+
+
diff --git a/frameworks/Java/aio-socket/aio-socket.dockerfile b/frameworks/Java/aio-socket/aio-socket.dockerfile
new file mode 100644
index 00000000000..7aa11987383
--- /dev/null
+++ b/frameworks/Java/aio-socket/aio-socket.dockerfile
@@ -0,0 +1,19 @@
+FROM litongjava/maven:3.8.8-jdk8u391 AS builder
+WORKDIR /app
+
+COPY pom.xml pom.xml
+RUN mvn dependency:go-offline -q
+
+COPY src src
+RUN mvn package -Passembly -q
+RUN ls -l && ls -l target
+
+FROM litongjava/jre:8u391-stable-slim
+
+WORKDIR /app
+
+COPY --from=builder /app/target/aio-socket-benchmark-1.0-jar-with-dependencies.jar /app/aio-socket-benchmark-1.0.jar
+
+EXPOSE 8080
+
+CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC","-cp", "/app/aio-socket-benchmark-1.0.jar","com.litongjava.aio.http.server.HttpServer"]
\ No newline at end of file
diff --git a/frameworks/Java/aio-socket/benchmark_config.json b/frameworks/Java/aio-socket/benchmark_config.json
new file mode 100644
index 00000000000..135582cd342
--- /dev/null
+++ b/frameworks/Java/aio-socket/benchmark_config.json
@@ -0,0 +1,23 @@
+{
+ "framework": "aio-socket",
+ "tests": [{
+ "default": {
+ "plaintext_url": "/plaintext",
+ "json_url": "/json",
+ "port": 8080,
+ "approach": "Realistic",
+ "classification": "Micro",
+ "framework": "aio-socket",
+ "language": "Java",
+ "flavor": "None",
+ "orm": "Raw",
+ "platform": "t-io",
+ "webserver": "None",
+ "os": "Linux",
+ "database_os": "Linux",
+ "display_name": "aio-socket",
+ "notes": "aio-socket",
+ "versus": "t-io"
+ }
+ }]
+}
diff --git a/frameworks/Java/aio-socket/config.toml b/frameworks/Java/aio-socket/config.toml
new file mode 100644
index 00000000000..31b198ee34b
--- /dev/null
+++ b/frameworks/Java/aio-socket/config.toml
@@ -0,0 +1,15 @@
+[framework]
+name = "t-io"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+approach = "Realistic"
+classification = "Micro"
+database = "None"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "t-io"
+webserver = "None"
+versus = "t-io"
diff --git a/frameworks/Java/aio-socket/pom.xml b/frameworks/Java/aio-socket/pom.xml
new file mode 100644
index 00000000000..2b5dacefe65
--- /dev/null
+++ b/frameworks/Java/aio-socket/pom.xml
@@ -0,0 +1,90 @@
+
+ 4.0.0
+ com.litongjava
+ aio-socket-benchmark
+ 1.0
+ ${project.artifactId}
+
+ UTF-8
+ 1.8
+ ${java.version}
+ ${java.version}
+ com.litongjava.aio.http.server.HttpServer
+
+
+
+ com.litongjava
+ aio-socket
+ 1.0.1
+
+
+ com.alibaba
+ fastjson
+ 2.0.39
+
+
+
+
+
+ central
+ Central Repository
+ https://repo.maven.apache.org/maven2
+
+
+ sonatype-nexus-snapshots
+ Sonatype Nexus Snapshots
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+
+
+ central
+ Central Repository
+ https://repo.maven.apache.org/maven2
+
+
+ sonatype-nexus-snapshots
+ Sonatype Nexus Snapshots
+ https://oss.sonatype.org/content/repositories/snapshots
+
+ false
+
+
+ true
+
+
+
+
+
+
+
+ true
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+ false
+
+
+
+
+ maven-assembly-plugin
+ 3.1.0
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/HttpServer.java b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/HttpServer.java
new file mode 100644
index 00000000000..fa954b4cef4
--- /dev/null
+++ b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/HttpServer.java
@@ -0,0 +1,169 @@
+package com.litongjava.aio.http.server;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousChannelGroup;
+import java.nio.channels.AsynchronousSocketChannel;
+import java.nio.channels.CompletionHandler;
+import java.nio.charset.StandardCharsets;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.ZoneId;
+import java.util.concurrent.ThreadFactory;
+
+import com.alibaba.fastjson.JSON;
+import com.litongjava.aio.http.server.model.Message;
+import com.litongjava.enhance.buffer.BufferPage;
+import com.litongjava.enhance.buffer.BufferPagePool;
+import com.litongjava.enhance.buffer.VirtualBuffer;
+import com.litongjava.enhance.channel.EnhanceAsynchronousChannelProvider;
+import com.litongjava.enhance.channel.EnhanceAsynchronousServerSocketChannel;
+
+public class HttpServer {
+
+ private static int cpuNum = Runtime.getRuntime().availableProcessors();
+ private static BufferPagePool pool = new BufferPagePool(0, 1024 * cpuNum, true);
+ private static BufferPage bufferPage = pool.allocateBufferPage();
+ private static final String HELLO_WORLD = "Hello, World!";
+
+ public static void main(String[] args) throws Exception {
+
+ // 创建异步通道提供者
+ EnhanceAsynchronousChannelProvider provider = new EnhanceAsynchronousChannelProvider(false);
+
+ // 创建通道组
+ AsynchronousChannelGroup group = provider.openAsynchronousChannelGroup(2, new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "http-server-thread");
+ }
+ });
+
+ // 创建服务器通道并绑定端口
+ EnhanceAsynchronousServerSocketChannel server = (EnhanceAsynchronousServerSocketChannel) provider.openAsynchronousServerSocketChannel(group);
+ server.bind(new InetSocketAddress(8080), 0);
+
+ System.out.println("HTTP Server 正在监听端口 8080 ...");
+
+ // 异步接受连接
+ server.accept(null, new CompletionHandler() {
+ @Override
+ public void completed(AsynchronousSocketChannel channel, Object attachment) {
+ // 继续接收其他连接
+ server.accept(null, this);
+ handleClient(channel);
+ }
+
+ @Override
+ public void failed(Throwable exc, Object attachment) {
+ exc.printStackTrace();
+ }
+ });
+
+ // 主线程阻塞
+ Thread.currentThread().join();
+ }
+
+ private static void handleClient(AsynchronousSocketChannel channel) {
+ VirtualBuffer virtualBuffer = bufferPage.allocate(8192);
+ ByteBuffer buffer = virtualBuffer.buffer();
+
+ channel.read(buffer, virtualBuffer, new CompletionHandler() {
+ @Override
+ public void completed(Integer result, VirtualBuffer attachment) {
+ try {
+ if (result > 0) {
+ buffer.flip();
+ byte[] bytes = new byte[buffer.remaining()];
+ buffer.get(bytes);
+ String request = new String(bytes, StandardCharsets.UTF_8);
+
+ // 生成当前时间,格式为 RFC 1123 格式
+ String date = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneId.of("GMT")));
+
+ ByteBuffer responseBuffer;
+ if (request.startsWith("GET /plaintext")) {
+ String body = "Hello, World!";
+ String httpResponse = "HTTP/1.1 200 OK\r\n" +
+ "Content-Length: " + body.getBytes(StandardCharsets.UTF_8).length + "\r\n" +
+ "Server: aio-socket\r\n" +
+ "Content-Type: text/plain\r\n" +
+ "Date: " + date + "\r\n" +
+ "\r\n" +
+ body;
+ responseBuffer = ByteBuffer.wrap(httpResponse.getBytes(StandardCharsets.UTF_8));
+
+ } else if (request.startsWith("GET /json")) {
+ String jsonString = JSON.toJSONString(new Message(HELLO_WORLD));
+ int length = jsonString.getBytes(StandardCharsets.UTF_8).length;
+ String httpResponse = "HTTP/1.1 200 OK\r\n" +
+ "Content-Length: " + length + "\r\n" +
+ "Server: aio-socket\r\n" +
+ "Content-Type: application/json\r\n" +
+ "Date: " + date + "\r\n" +
+ "\r\n" +
+ jsonString;
+ responseBuffer = ByteBuffer.wrap(httpResponse.getBytes(StandardCharsets.UTF_8));
+ } else {
+ String body = "Hello, World!";
+ String httpResponse = "HTTP/1.1 200 OK\r\n" +
+ "Content-Length: " + body.getBytes(StandardCharsets.UTF_8).length + "\r\n" +
+ "Content-Type: text/plain\r\n" +
+ "Date: " + date + "\r\n" +
+ "\r\n" +
+ body;
+ responseBuffer = ByteBuffer.wrap(httpResponse.getBytes(StandardCharsets.UTF_8));
+ }
+
+ // 异步写响应
+ channel.write(responseBuffer, attachment, new CompletionHandler() {
+ @Override
+ public void completed(Integer result, VirtualBuffer attachment) {
+ try {
+ channel.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ attachment.clean();
+ }
+ }
+
+ @Override
+ public void failed(Throwable exc, VirtualBuffer attachment) {
+ exc.printStackTrace();
+ try {
+ channel.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ attachment.clean();
+ }
+ }
+ });
+ } else {
+ try {
+ channel.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ } finally {
+ // 注意:如果在写操作中已经归还了虚拟缓冲区,则不要重复释放
+ }
+ }
+
+ @Override
+ public void failed(Throwable exc, VirtualBuffer attachment) {
+ exc.printStackTrace();
+ try {
+ channel.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ attachment.clean();
+ }
+ }
+ });
+ }
+}
diff --git a/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/model/Fortune.java b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/model/Fortune.java
new file mode 100644
index 00000000000..76f56b22dc9
--- /dev/null
+++ b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/model/Fortune.java
@@ -0,0 +1,23 @@
+package com.litongjava.aio.http.server.model;
+
+public final class Fortune {
+
+ public Long id;
+ public String message;
+
+ public Fortune() {
+ }
+
+ public Fortune(Long id, String message) {
+ this.id = id;
+ this.message = message;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
\ No newline at end of file
diff --git a/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/model/Message.java b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/model/Message.java
new file mode 100644
index 00000000000..2365bf4d708
--- /dev/null
+++ b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/model/Message.java
@@ -0,0 +1,13 @@
+package com.litongjava.aio.http.server.model;
+
+public final class Message {
+ private final String message;
+
+ public Message(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/model/World.java b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/model/World.java
new file mode 100644
index 00000000000..3fec0068ea5
--- /dev/null
+++ b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/model/World.java
@@ -0,0 +1,32 @@
+package com.litongjava.aio.http.server.model;
+
+public final class World {
+
+ public int id;
+ public int randomnumber;
+
+ protected World() {
+ }
+
+ public World(int id, int randomnumber) {
+ this.id = id;
+ this.randomnumber = randomnumber;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getRandomnumber() {
+ return randomnumber;
+ }
+
+ public void setRandomnumber(int randomnumber) {
+ this.randomnumber = randomnumber;
+ }
+
+}
\ No newline at end of file
diff --git a/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/utils/RandomUtils.java b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/utils/RandomUtils.java
new file mode 100644
index 00000000000..c2b73f8dca2
--- /dev/null
+++ b/frameworks/Java/aio-socket/src/main/java/com/litongjava/aio/http/server/utils/RandomUtils.java
@@ -0,0 +1,36 @@
+package com.litongjava.aio.http.server.utils;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.IntStream;
+
+public class RandomUtils {
+
+ private static final int MIN_WORLD_NUMBER = 1;
+ private static final int MAX_WORLD_NUMBER_PLUS_ONE = 10_001;
+ // private static final int MAX_WORLD_NUMBER_PLUS_ONE = 30;
+
+ public static int randomWorldNumber() {
+ return ThreadLocalRandom.current().nextInt(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER_PLUS_ONE);
+ }
+
+ public static IntStream randomWorldNumbers() {
+ return ThreadLocalRandom.current().ints(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER_PLUS_ONE)
+ // distinct() allows us to avoid using Hibernate's first-level cache in
+ // the JPA-based implementation. Using a cache like that would bypass
+ // querying the database, which would violate the test requirements.
+ .distinct();
+ }
+
+ public static int parseQueryCount(String textValue) {
+ if (textValue == null) {
+ return 1;
+ }
+ int parsedValue;
+ try {
+ parsedValue = Integer.parseInt(textValue);
+ } catch (NumberFormatException e) {
+ return 1;
+ }
+ return Math.min(500, Math.max(1, parsedValue));
+ }
+}
diff --git a/frameworks/Java/aio-socket/src/main/resources/app.properties b/frameworks/Java/aio-socket/src/main/resources/app.properties
new file mode 100644
index 00000000000..52083ea13ff
--- /dev/null
+++ b/frameworks/Java/aio-socket/src/main/resources/app.properties
@@ -0,0 +1,9 @@
+http.response.header.showServer=true
+server.port=8080
+#JDBC_URL=jdbc:mysql://192.168.3.9/hello_world?useSSL=false&allowPublicKeyRetrieval=true
+#JDBC_USER=root
+#JDBC_PSWD=robot_123456#
+
+JDBC_URL=jdbc:mysql://tfb-database/hello_world
+JDBC_USER=benchmarkdbuser
+JDBC_PSWD=benchmarkdbpass
\ No newline at end of file
diff --git a/frameworks/Java/aio-socket/src/main/resources/ehcache.xml b/frameworks/Java/aio-socket/src/main/resources/ehcache.xml
new file mode 100644
index 00000000000..79b79e49479
--- /dev/null
+++ b/frameworks/Java/aio-socket/src/main/resources/ehcache.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/frameworks/Java/aio-socket/src/main/resources/logback.xml b/frameworks/Java/aio-socket/src/main/resources/logback.xml
new file mode 100644
index 00000000000..6065c075e78
--- /dev/null
+++ b/frameworks/Java/aio-socket/src/main/resources/logback.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ ${CONSOLE_LOG_PATTERN}
+
+
+
+
+
+
+ ${CONSOLE_LOG_PATTERN}
+
+
+
+ ${LOG_HOME}/log.%d{yyyyMMddHH}.%i.log
+
+ 180
+
+ 100MB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frameworks/Java/aio-socket/src/main/resources/templates/fortunes.html b/frameworks/Java/aio-socket/src/main/resources/templates/fortunes.html
new file mode 100644
index 00000000000..1f6817df007
--- /dev/null
+++ b/frameworks/Java/aio-socket/src/main/resources/templates/fortunes.html
@@ -0,0 +1,20 @@
+
+
+
+ Fortunes
+
+
+
+
+ | id |
+ message |
+
+ #for(fortune : fortunes)
+
+ | #(fortune.id) |
+ #escape(fortune.message) |
+
+ #end
+
+
+