|
| 1 | +# 性能记录 |
| 2 | + |
| 3 | +## 测试日期 |
| 4 | + |
| 5 | +2026-04-14 |
| 6 | + |
| 7 | +## 测试范围 |
| 8 | + |
| 9 | +本文记录当前 `KTcpServer` 实现的一次本地 benchmark 结果。 |
| 10 | + |
| 11 | +本次测试 **不经过 HTTP 解析路径**,目标是测试 TCP 核心链路: |
| 12 | + |
| 13 | +- `TcpServer` |
| 14 | +- `TcpConnection` |
| 15 | +- `Buffer` |
| 16 | +- 事件循环 / poller / 线程池分发 |
| 17 | + |
| 18 | +benchmark 通过一个直接构建在 `KTcpServer` 之上的 echo server 进行压测,因此更适合作为传输层基线,而不是 HTTP 层 QPS 数据。 |
| 19 | + |
| 20 | +Benchmark 源文件: |
| 21 | + |
| 22 | +- [`webserver/benchmark_kTcpServer.cpp`](./webserver/benchmark_kTcpServer.cpp) |
| 23 | + |
| 24 | +## 测试环境 |
| 25 | + |
| 26 | +- Repository: `WebServer` |
| 27 | +- Compiler: `g++ 10.2.1` |
| 28 | +- 构建时安装的依赖: `boost-devel` |
| 29 | +- 测试方式: localhost `127.0.0.1` |
| 30 | +- Benchmark 可执行文件: `webserver/benchmark_kTcpServer` |
| 31 | + |
| 32 | +## 测试方法 |
| 33 | + |
| 34 | +- benchmark 会先启动一个基于 `KTcpServer` 的本地 echo server。 |
| 35 | +- 多个 client 线程通过 TCP 建立连接,并在整个测试过程中保持长连接。 |
| 36 | +- 只有当所有 client 都连接完成并进入 ready 状态后,才开始计时。 |
| 37 | +- 每次请求发送固定大小的 payload,并等待服务端原样回显后再进入下一轮。 |
| 38 | +- 因此这里测到的是稳定态下的 request/response throughput,而不是建连成本。 |
| 39 | + |
| 40 | +## 编译命令 |
| 41 | + |
| 42 | +在 `webserver/` 目录下执行: |
| 43 | + |
| 44 | +```bash |
| 45 | +g++ -I . -O2 -std=c++11 -D NDEBUG runHttpServer.cpp \ |
| 46 | + loop/KEventLoop.cpp loop/KEventLoopThread.cpp loop/KEventLoopThreadPool.cpp loop/KAsyncWaker.cpp \ |
| 47 | + thread/KThreadPool.cpp poller/KChannel.cpp poller/KEventManager.cpp utils/KTimestamp.cpp \ |
| 48 | + tcp/KSocket.cpp tcp/KSocketsOps.cpp tcp/KInetAddress.cpp tcp/KAcceptor.cpp tcp/KTcpServer.cpp tcp/KTcpConnection.cpp tcp/KBuffer.cpp tcp/KRingBuffer.cpp \ |
| 49 | + http/KHttpResponse.cpp http/KHttpContext.cpp http/KHttpServer.cpp http/KIcons.cpp \ |
| 50 | + -o runHttpServer -lpthread |
| 51 | + |
| 52 | +g++ -I . -O2 -std=c++11 -D NDEBUG benchmark_kTcpServer.cpp \ |
| 53 | + loop/KEventLoop.cpp loop/KEventLoopThread.cpp loop/KEventLoopThreadPool.cpp loop/KAsyncWaker.cpp \ |
| 54 | + thread/KThreadPool.cpp poller/KChannel.cpp poller/KEventManager.cpp utils/KTimestamp.cpp \ |
| 55 | + tcp/KSocket.cpp tcp/KSocketsOps.cpp tcp/KInetAddress.cpp tcp/KAcceptor.cpp tcp/KTcpServer.cpp tcp/KTcpConnection.cpp tcp/KBuffer.cpp tcp/KRingBuffer.cpp \ |
| 56 | + http/KHttpResponse.cpp http/KHttpContext.cpp http/KHttpServer.cpp http/KIcons.cpp \ |
| 57 | + -o benchmark_kTcpServer -lpthread |
| 58 | +``` |
| 59 | + |
| 60 | +## 执行命令 |
| 61 | + |
| 62 | +```bash |
| 63 | +./benchmark_kTcpServer --io-threads 3 --client-threads 8 --requests-per-thread 20000 --payload-size 64 |
| 64 | +./benchmark_kTcpServer --io-threads 3 --client-threads 8 --requests-per-thread 20000 --payload-size 1024 |
| 65 | +``` |
| 66 | + |
| 67 | +## 测试结果 |
| 68 | + |
| 69 | +| io_threads | client_threads | requests_per_thread | payload_size | total_requests | elapsed_seconds | throughput_req_per_sec | throughput_mib_per_sec | avg_round_trip_us_per_connection | |
| 70 | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | |
| 71 | +| 3 | 8 | 20000 | 64 B | 160000 | 0.45 | 357486.96 | 21.82 | 22.38 | |
| 72 | +| 3 | 8 | 20000 | 1024 B | 160000 | 0.47 | 339615.77 | 331.66 | 23.56 | |
| 73 | + |
| 74 | +## 原始输出 |
| 75 | + |
| 76 | +### 64-byte payload |
| 77 | + |
| 78 | +```text |
| 79 | +Benchmark: KTcpServer echo round-trip |
| 80 | + port: 18888 |
| 81 | + io_threads: 3 |
| 82 | + client_threads: 8 |
| 83 | + requests_per_thread: 20000 |
| 84 | + payload_size_bytes: 64 |
| 85 | +Results: |
| 86 | + total_requests: 160000 |
| 87 | + total_bytes: 10240000 |
| 88 | + elapsed_seconds: 0.45 |
| 89 | + throughput_req_per_sec: 357486.96 |
| 90 | + throughput_mib_per_sec: 21.82 |
| 91 | + avg_round_trip_us_per_connection: 22.38 |
| 92 | +Server stats: |
| 93 | + accepted_connections: 8 |
| 94 | + closed_connections: 8 |
| 95 | + echoed_messages: 160000 |
| 96 | + echoed_bytes: 10240000 |
| 97 | +``` |
| 98 | + |
| 99 | +### 1024-byte payload |
| 100 | + |
| 101 | +```text |
| 102 | +Benchmark: KTcpServer echo round-trip |
| 103 | + port: 18888 |
| 104 | + io_threads: 3 |
| 105 | + client_threads: 8 |
| 106 | + requests_per_thread: 20000 |
| 107 | + payload_size_bytes: 1024 |
| 108 | +Results: |
| 109 | + total_requests: 160000 |
| 110 | + total_bytes: 163840000 |
| 111 | + elapsed_seconds: 0.47 |
| 112 | + throughput_req_per_sec: 339615.77 |
| 113 | + throughput_mib_per_sec: 331.66 |
| 114 | + avg_round_trip_us_per_connection: 23.56 |
| 115 | +Server stats: |
| 116 | + accepted_connections: 8 |
| 117 | + closed_connections: 8 |
| 118 | + echoed_messages: 160000 |
| 119 | + echoed_bytes: 163840000 |
| 120 | +``` |
| 121 | + |
| 122 | +## 说明 |
| 123 | + |
| 124 | +- 这些数据来自当前机器上的 localhost loopback,只适合作为本机基线,不等价于跨主机网络环境下的真实表现。 |
| 125 | +- 这个 benchmark 有意绕过了 HTTP 层,因此结果应理解为 `KTcpServer` 的传输层能力,而不是完整 webserver 的 HTTP QPS。 |
| 126 | +- 建连过程不计入最终统计时间窗口。 |
0 commit comments