Skip to content

Commit 8a63715

Browse files
refactor: 优化中间件架构并修复多个问题 (#108)
* refactor(core): 优化请求解析方法的语义分离 - 将 application/x-www-form-urlencoded 处理从 json_parse 移到 form_parse - json_parse 现在仅处理 application/json 数据,移除不必要的 Serialize 约束 - form_parse 支持 multipart/form-data 和 application/x-www-form-urlencoded - 实现统一缓存策略:WWW_FORM_URLENCODED 数据缓存到 json_data 字段 - 为 multipart/form-data 复用 form_data 缓存机制 - 添加完整的测试用例验证语义分离和缓存机制 - 更新 examples/form 示例使用正确的 form_parse 方法 BREAKING CHANGE: json_parse 不再支持 application/x-www-form-urlencoded 迁移指南:使用 form_parse() 替代 json_parse() 处理表单数据 * refactor(route): 统一路由处理架构,移除RootRoute结构 - 移除 RootRoute 结构体,将其功能完全融合到 Route 中 - 统一路由匹配逻辑,消除根路由和普通路由的人工区分 - 通过 configs 字段自然识别服务入口点,无需额外标志位 - 简化路由处理流程,减少代码重复和条件分支 - 保持所有原有功能和API兼容性 - 优化中间件层级管理和执行顺序 - 更新所有测试和示例以使用统一的Route结构 BREAKING CHANGE: RootRoute 类型已被移除,使用 Route::new_root() 替代 * fix(route): 修复路由匹配优先级和configs传递问题 修复了路由匹配逻辑中的优先级问题: 1. 空路径路由优先检查子路由,避免错误匹配 2. 非空路径路由优先匹配子路由,再检查自身处理器 3. 修复Server::serve中configs设置逻辑,避免覆盖已有configs 4. 确保路由匹配时正确传递configs信息 5. 移除调试信息,清理代码 解决了以下问题: - 根路径/返回404而不是root_handler - /api/v1/users返回hello处理器内容而不是user_handler - 路由匹配优先级错误导致的功能异常 现在所有路由都能正确匹配到对应处理器,中间件层级管理正常。 * style(route): 清理调试信息和代码格式 移除所有调试用的 println! 语句,保持代码整洁: 1. 移除 handler_append.rs 中的调试输出 2. 移除 handler_match.rs 中的调试输出 3. 移除 route/mod.rs 中的调试输出 4. 移除 service/mod.rs 中的调试输出 5. 清理代码格式,移除多余的空行 保持核心功能不变,只是清理了调试信息。 * style(route): 进一步清理调试信息和优化代码格式 继续清理剩余的调试信息: 1. 移除 LayeredHandler 中的调试输出 2. 移除 handle_as_service_entry 中的调试输出 3. 移除 Route::call 中的调试输出 4. 移除未使用的循环变量 i 5. 优化代码格式和导入顺序 保持核心功能不变,进一步清理代码。 * fix(route): 修复空路径路由匹配问题并添加10层复杂路由benchmark 修复了路由匹配中空路径路由无法正确匹配的问题: - 修复 last_matched 方法中空路径路由的子路由匹配逻辑 - 解决了 empty_path_edge_case_test、nested_empty_path_test 和 root_route_matching_test 三个测试失败的问题 - 确保空路径路由(如 Route::new('').get(handler))能够正确匹配根路径 '/' 添加了全面的路由匹配性能benchmark: - 创建10层深度嵌套路由的benchmark测试 - 包含静态路径、参数路径、中间件和混合类型的复杂路由测试 - 添加路由深度性能对比测试(3层、5层、7层、10层) - 生成详细的性能测试报告 性能测试结果显示: - 10层深度路由匹配性能约240ns,表现良好 - 参数解析开销约41%,中间件影响很小 - 性能随路由深度线性增长,可预测性强 修复了clippy警告: - 将 assert_eq!(bool, true) 改为 assert!(bool) - 将 assert!(false) 改为 unreachable!() Closes #路由匹配问题 * fix(deps): 修复prost和tonic版本冲突问题 修复了gRPC示例中的依赖版本冲突问题: - 将prost版本从0.14回退到0.13,与tonic 0.13兼容 - 解决了多个gRPC示例编译失败的问题 - 确保所有示例都能正常编译和运行 这个修复解决了以下错误: - 'prost::message::Message' trait不匹配的问题 - tonic-build API兼容性问题 - 依赖树中多个prost版本冲突的问题 现在cargo check --all可以正常通过。 * fix(cookie): 修复CookieExt::cookies_mut方法中的unwrap panic问题 修复了CookieExt trait中cookies_mut方法的潜在panic问题: - 在Request和Response的cookies_mut方法中添加了CookieJar初始化逻辑 - 当extensions中不存在CookieJar时,自动创建并插入新的CookieJar实例 - 避免了调用unwrap()时因为None值导致的panic 这个修复解决了cookies示例中的运行时panic问题: - 修复前:调用res.cookies_mut()时如果CookieJar不存在会panic - 修复后:自动初始化CookieJar,确保方法调用安全 测试验证: - cookies示例现在可以正常运行,不再出现panic - 所有单元测试通过 - clippy检查通过 - cargo check --all通过 * fix(merge): 解决Cargo.toml合并冲突并回退tonic版本 - 移除Git冲突标记 - 清理重复的依赖项定义 - 回退tonic相关依赖到0.13版本以保持API兼容性 - 为middleware_layered示例添加Apache-2.0许可证 - 更新Cargo.lock文件 - 格式化代码以符合rustfmt标准
1 parent 3e477e2 commit 8a63715

File tree

22 files changed

+1404
-264
lines changed

22 files changed

+1404
-264
lines changed

Cargo.toml

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[workspace]
2-
members = ["silent", "examples/*", "benchmark"]
32
default-members = ["silent"]
4-
resolver = "3"
3+
members = ["silent", "benchmark", "examples/*"]
4+
resolver = "2"
55

66
[workspace.package]
7-
edition = "2024"
87
authors = ["Hubert Shelley <hubertshelley@163.com>"]
8+
edition = "2024"
99
homepage = "https://github.com/silent-rs/silent"
1010
license = "Apache-2.0"
1111
readme = "./readme.md"
@@ -14,24 +14,24 @@ version = "2.5.2"
1414

1515
[workspace.dependencies]
1616
async-trait = "0.1.88"
17-
tokio = { version = "1", features = ["full"] }
18-
tonic = "0.14"
19-
prost = "0.14"
17+
chrono = "0.4"
18+
dlopen2 = {version = "0.8", features = ["derive"]}
19+
futures-util = "0.3"
20+
h2 = "0.4"
21+
headers = "0.4"
2022
http = "1"
21-
hyper-util = "0.1"
2223
hyper = "1"
23-
tower = "0.5"
24-
tonic-build = "0.14"
25-
tokio_wasi = { version = "1", features = ["full"] }
26-
tokio-stream = { version = "0.1", features = ["net"] }
27-
futures-util = "0.3"
24+
hyper-util = "0.1"
2825
once_cell = "1"
26+
parking_lot = "0.12"
27+
prost = "0.13"
28+
serde = {version = "1", features = ["derive"]}
29+
tokio = {version = "1", features = ["full"]}
30+
tokio-stream = {version = "0.1", features = ["net"]}
2931
tokio-tungstenite = "0.27"
32+
tokio_wasi = {version = "1", features = ["full"]}
33+
tonic = "0.13"
34+
tonic-build = "0.13"
35+
tower = "0.5"
3036
tracing-subscriber = "0.3"
31-
headers = "0.4"
32-
serde = { version = "1", features = ["derive"] }
33-
uuid = { version = "1", features = ["serde", "v4"] }
34-
parking_lot = "0.12"
35-
chrono = "0.4"
36-
dlopen2 = { version = "0.8", features = ["derive"] }
37-
h2 = "0.4"
37+
uuid = {version = "1", features = ["serde", "v4"]}

benchmark/README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Silent 路由匹配性能基准测试报告
2+
3+
## 概述
4+
5+
本报告展示了 Silent 框架中路由匹配功能的性能基准测试结果,特别关注10层复杂路由的匹配性能。
6+
7+
## 测试环境
8+
9+
- **框架版本**: Silent v2.5.2
10+
- **Rust版本**: 1.88.0
11+
- **测试平台**: macOS (darwin 24.5.0)
12+
- **编译模式**: Release (优化模式)
13+
14+
## 测试场景
15+
16+
### 1. 基础路由测试
17+
18+
| 测试场景 | 平均耗时 | 性能表现 |
19+
|---------|---------|---------|
20+
| 简单路由匹配 | ~104 ns | 优秀 |
21+
| 嵌套路由匹配 | ~155 ns | 良好 |
22+
| 带中间件路由 | ~107 ns | 优秀 |
23+
| 多中间件路由 | ~105 ns | 优秀 |
24+
25+
### 2. 复杂路由测试
26+
27+
| 测试场景 | 平均耗时 | 性能表现 |
28+
|---------|---------|---------|
29+
| GET /api/v1/users | ~163 ns | 良好 |
30+
| POST /api/v1/posts | ~161 ns | 良好 |
31+
| GET /api/v1/posts/comments | ~172 ns | 良好 |
32+
33+
### 3. 10层深度嵌套路由测试
34+
35+
#### 3.1 静态路径路由
36+
37+
| 测试场景 | 平均耗时 | 性能表现 |
38+
|---------|---------|---------|
39+
| 匹配最深路由 | ~233 ns | 良好 |
40+
| 匹配中间层路由 | ~202 ns | 良好 |
41+
| 不匹配路由 | ~235 ns | 良好 |
42+
43+
#### 3.2 带参数路由
44+
45+
| 测试场景 | 平均耗时 | 性能表现 |
46+
|---------|---------|---------|
47+
| 匹配最深路由(带参数) | ~329 ns | 良好 |
48+
| 匹配中间层路由(带参数) | ~227 ns | 良好 |
49+
50+
#### 3.3 带中间件路由
51+
52+
| 测试场景 | 平均耗时 | 性能表现 |
53+
|---------|---------|---------|
54+
| 匹配最深路由(带中间件) | ~231 ns | 良好 |
55+
56+
#### 3.4 混合类型路由
57+
58+
| 测试场景 | 平均耗时 | 性能表现 |
59+
|---------|---------|---------|
60+
| 匹配最深混合路由 | ~288 ns | 良好 |
61+
| 匹配中间层混合路由 | ~230 ns | 良好 |
62+
63+
### 4. 路由深度性能对比
64+
65+
| 路由深度 | 平均耗时 | 性能趋势 |
66+
|---------|---------|---------|
67+
| 3层路由 | ~171 ns | 基准 |
68+
| 5层路由 | ~192 ns | +12% |
69+
| 7层路由 | ~210 ns | +23% |
70+
| 10层路由 | ~240 ns | +40% |
71+
72+
## 性能分析
73+
74+
### 1. 路由深度对性能的影响
75+
76+
从测试结果可以看出,路由深度对性能有一定影响,但影响相对较小:
77+
78+
- **3层到10层**: 性能下降约40%
79+
- **每增加一层**: 平均增加约10-15ns
80+
- **线性增长**: 性能下降基本呈线性关系
81+
82+
### 2. 参数解析的性能开销
83+
84+
带路径参数的路由比静态路由慢约30-40%:
85+
86+
- **静态路由**: ~233 ns
87+
- **参数路由**: ~329 ns
88+
- **性能差异**: 约41%的开销
89+
90+
### 3. 中间件的影响
91+
92+
中间件对路由匹配性能的影响很小:
93+
94+
- **无中间件**: ~233 ns
95+
- **有中间件**: ~231 ns
96+
- **性能差异**: 几乎无影响
97+
98+
### 4. 高负载测试
99+
100+
1000个连续请求的处理时间约为225μs,平均每个请求约225ns,说明在高负载下性能保持稳定。
101+
102+
## 优化建议
103+
104+
### 1. 路由设计优化
105+
106+
- **避免过深嵌套**: 建议路由深度不超过7层
107+
- **合理使用参数**: 参数路由比静态路由慢,应适度使用
108+
- **中间件优化**: 中间件对匹配性能影响很小,可以放心使用
109+
110+
### 2. 性能优化方向
111+
112+
- **路由树优化**: 可以考虑使用更高效的路由树结构
113+
- **参数解析优化**: 参数解析是主要性能瓶颈,可以进一步优化
114+
- **缓存机制**: 对于频繁访问的路由可以考虑添加缓存
115+
116+
## 结论
117+
118+
Silent 框架的路由匹配性能表现优秀:
119+
120+
1. **基础性能**: 简单路由匹配在100ns左右,性能优秀
121+
2. **深度支持**: 10层深度路由仍能保持良好性能(~240ns)
122+
3. **功能完整**: 支持参数、中间件等高级功能,且性能影响可控
123+
4. **线性扩展**: 性能随路由深度线性增长,可预测性好
124+
125+
总体而言,Silent 的路由匹配功能在保持功能完整性的同时,提供了优秀的性能表现,适合构建复杂的Web应用。
126+
127+
## 测试代码
128+
129+
详细的测试代码请参考 `benches/route_benchmark.rs` 文件,包含了各种复杂场景的基准测试。

0 commit comments

Comments
 (0)