perf: 静态路由修改为简单的map缓存

This commit is contained in:
meiseayoung
2025-12-29 12:14:20 +08:00
parent 7c1aa656ab
commit 3ef232a077
12 changed files with 990 additions and 404 deletions
+45
View File
@@ -0,0 +1,45 @@
# V 语言 HTTP Keep-Alive 问题最小复现
## 问题描述
V 语言标准库 `net.http.Server` 不支持 HTTP Keep-Alive 连接复用。
每次请求处理完成后,服务器会立即关闭 TCP 连接。
## 运行方式
### 1. 启动服务器
```bash
v run server.v
```
### 2. 运行客户端测试(新终端)
```bash
v run client.v
```
## 预期 vs 实际
| 请求 | 预期 (Keep-Alive 正常) | 实际 (V 当前行为) |
|------|------------------------|-------------------|
| #1 | ~300ms (新连接) | ~300ms |
| #2 | ~1-10ms (复用) | ~300ms |
| #3 | ~1-10ms (复用) | ~300ms |
| #4 | ~1-10ms (复用) | ~300ms |
| #5 | ~1-10ms (复用) | ~300ms |
## 根本原因
`vlib/net/http/server.v` 中的 `handle_conn` 函数:
```v
fn (mut w HandlerWorker) handle_conn(mut conn net.TcpConn) {
defer {
conn.close() or { ... } // <-- 每次请求后关闭连接
}
// 只处理单个请求,然后关闭
}
```
## 临时解决方案
在 V 服务器前部署 nginx 等反向代理来处理 Keep-Alive。
+34
View File
@@ -0,0 +1,34 @@
// Minimal client example - Test Keep-Alive connection reuse
module main
import net.http
import time
fn main() {
println('=== V HTTP Keep-Alive Issue Demo ===\n')
println('Sending 5 consecutive requests, observe the time for each...\n')
url := 'http://127.0.0.1:8080/'
for i in 1 .. 6 {
start := time.now()
resp := http.get(url) or {
println('Request failed: ${err}')
continue
}
elapsed := time.since(start)
println('Request #${i}: ${elapsed.milliseconds()}ms - Status: ${resp.status_code}')
}
println('\n--- Analysis ---')
println('If Keep-Alive works correctly:')
println(' - First request: ~300ms (establish TCP connection)')
println(' - Subsequent requests: ~1-10ms (reuse connection)')
println('')
println('Actual behavior (V language current):')
println(' - Every request takes ~300ms (reconnect each time)')
println('')
println('Reason: net.http.Server calls conn.close() after each request')
}
+34
View File
@@ -0,0 +1,34 @@
// Minimal server example - Demonstrate Keep-Alive issue
module main
import net.http
import time
struct MyHandler {}
fn (_ MyHandler) handle(req http.Request) http.Response {
now := time.now()
println('[${now.format_ss_micro()}] Received request: ${req.method} ${req.url}')
return http.Response{
status_code: 200
status_msg: 'OK'
header: http.new_custom_header_from_map({
'Content-Type': 'text/plain'
'Connection': 'keep-alive' // Set but not effective
}) or { http.new_header() }
body: 'Hello! Time: ${now.format_ss_micro()}'
}
}
fn main() {
println('Starting server at http://localhost:8080')
println('Server sends Connection: keep-alive in response header')
println('But due to V stdlib limitation, connection is still closed')
mut server := http.Server{
handler: MyHandler{}
addr: ':8080'
}
server.listen_and_serve()
}