撮合引擎压力测试指南
版本: v0.2.0 更新日期: 2025-12-17 开发团队: @yutiansut @quantaxis
📋 目录
测试概述
压力测试目标
| 测试维度 | 目标 | 验证方法 |
|---|---|---|
| 多标的 | 支持100+合约并发 | 多线程多合约撮合 |
| 多用户 | 支持10,000+用户 | 大规模订单提交 |
| 吞吐量 | > 100,000 orders/sec | 高频下单测试 |
| 延迟 | P99 < 100μs | 延迟统计分析 |
| 并发 | 无数据竞争 | 多线程读写测试 |
| 稳定性 | 长时间无崩溃 | 极端场景测试 |
测试分类
压力测试 (19个)
├── 9. 多标的并发撮合 (3个)
│ ├── test_multi_instrument_concurrent_orders
│ ├── test_multi_instrument_parallel_matching
│ └── test_multi_instrument_isolation
├── 10. 多用户多账户 (3个)
│ ├── test_large_scale_users
│ ├── test_multi_account_order_distribution
│ └── test_cross_account_matching
├── 11. 吞吐量压力 (3个)
│ ├── test_throughput_single_instrument
│ ├── test_throughput_batch_matching
│ └── test_deep_orderbook
├── 12. 延迟基准 (3个)
│ ├── test_latency_single_order
│ ├── test_latency_matching
│ └── test_latency_deep_matching
├── 13. 并发安全 (3个)
│ ├── test_concurrent_read_write
│ ├── test_high_concurrency_orders
│ └── test_concurrent_cancel
└── 14. 极端场景 (4个)
├── test_extreme_price_range
├── test_orderbook_rebuild_after_mass_cancel
├── test_mixed_workload_stress
└── test_massive_order_submission
多标的压力测试
9.1 多标的同时下单
测试函数: test_multi_instrument_concurrent_orders
场景描述:
注册: 10个合约 (TEST0000 ~ TEST0009)
每合约:
- 100个买单 (价格990~891)
- 100个卖单 (价格1010~1109)
总订单: 2,000个
验证点:
- 所有合约正确注册
- 订单正确分配到各合约
- 无跨合约数据污染
运行命令:
cargo test test_multi_instrument_concurrent_orders --lib -- --nocapture
9.2 多标的并发撮合
测试函数: test_multi_instrument_parallel_matching
场景描述:
合约数: 5个 (PARA0000 ~ PARA0004)
线程数: 5个 (每合约1个线程)
每线程:
- 50对买卖单
- 每对先挂卖单再买单成交
预期成交: 250笔 (5 × 50)
架构图:
Thread-0 ──┬──> Orderbook(PARA0000) ──> 50 trades
Thread-1 ──┼──> Orderbook(PARA0001) ──> 50 trades
Thread-2 ──┼──> Orderbook(PARA0002) ──> 50 trades
Thread-3 ──┼──> Orderbook(PARA0003) ──> 50 trades
Thread-4 ──┴──> Orderbook(PARA0004) ──> 50 trades
─────────
250 trades
验证点:
- 所有线程完成无panic
- 成交数 = 250
- DashMap + RwLock 并发安全
9.3 多标的隔离性验证
测试函数: test_multi_instrument_isolation
场景描述:
合约A: 挂买单 @1000 × 100
合约B: 挂卖单 @1000 × 100
验证: 合约B的卖单不应与合约A的买单成交
验证点:
- 合约A买单状态: Accepted
- 合约B卖单状态: Accepted (而非Filled)
- 无跨合约撮合
多用户多账户测试
10.1 大量用户模拟
测试函数: test_large_scale_users
场景描述:
用户数: 1,000
订单分布:
- 用户0-499: 买单 (价格900-949)
- 用户500-999: 卖单 (价格1051-1100)
触发撮合: 大买单 @1200 × 500
验证点:
- 1,000个订单全部接受
- 大买单与500+卖单成交
- 系统稳定无崩溃
10.2 多账户订单均衡
测试函数: test_multi_account_order_distribution
场景描述:
账户数: 100
每账户订单: 10
总订单: 1,000
订单类型: 交替买卖 (不成交)
验证点:
- 接受订单数 = 1,000
- 买卖订单均匀分布
10.3 账户间成交验证
测试函数: test_cross_account_matching
场景描述:
卖方账户: 50个,每户卖单 @1000 × 10
买方账户: 50个,每户买单 @1000 × 10
验证点:
- 跨账户正常成交
- 成交数 >= 50
吞吐量压力测试
11.1 单合约高频下单
测试函数: test_throughput_single_instrument
测试参数:
#![allow(unused)] fn main() { let order_count = 10_000; // 买卖交替,价格不交叉,不触发撮合 }
性能指标: | 指标 | 目标 | 实际 | |------|------|------| | 吞吐量 | > 100K/s | ~300K/s | | 总耗时 | < 100ms | ~33ms |
运行命令:
cargo test test_throughput_single_instrument --lib --release -- --nocapture
11.2 批量撮合性能
测试函数: test_throughput_batch_matching
测试参数:
#![allow(unused)] fn main() { // 预挂5,000卖单 // 大买单一次消耗所有 let aggressive_buy = orders::new_limit_order_request( asset, OrderDirection::BUY, 1200.0, 5000.0, ts + 10000, ); }
性能指标: | 指标 | 目标 | 实际 | |------|------|------| | 撮合速率 | > 100K/s | ~800K/s | | 单次撮合 | < 10μs | ~1.25μs |
11.3 深度订单簿压力
测试函数: test_deep_orderbook
测试参数:
#![allow(unused)] fn main() { let depth = 10_000; // 每边10,000档 }
性能指标: | 指标 | 实际 | |------|------| | 构建耗时 | ~150ms | | 每档耗时 | ~7.5μs |
延迟基准测试
12.1 单订单延迟
测试函数: test_latency_single_order
测试方法:
#![allow(unused)] fn main() { let sample_count = 1000; for i in 0..sample_count { let start = Instant::now(); ob.process_order(order); latencies.push(start.elapsed().as_nanos()); } }
结果统计:
P50: 3.09 μs
P99: 6.11 μs
Avg: 3.28 μs
12.2 撮合延迟
测试函数: test_latency_matching
测试方法:
#![allow(unused)] fn main() { // 每次先挂卖单,再测量买单撮合延迟 for i in 0..500 { ob.process_order(sell); // 挂卖单 let start = Instant::now(); ob.process_order(buy); // 撮合 latencies.push(start.elapsed().as_nanos()); } }
结果统计:
P50: 2.22 μs
P99: 2.40 μs
Avg: 2.29 μs
12.3 深度撮合延迟
测试函数: test_latency_deep_matching
测试方法:
- 构建100档卖盘
- 大买单吃掉所有
- 重复10轮取平均
结果统计:
平均: 190.74 μs
最大: 233.66 μs
并发安全测试
13.1 多线程并发读写
测试函数: test_concurrent_read_write
线程分配:
写线程 × 4: 每线程提交100订单
读线程 × 4: 每线程读取100次lastprice
验证点:
- 所有线程无panic
- 无数据竞争
- 数据一致性
13.2 高并发下单
测试函数: test_high_concurrency_orders
参数:
#![allow(unused)] fn main() { let thread_count = 8; let orders_per_thread = 500; // 奇数线程买,偶数线程卖 // 统一价格可能触发成交 }
验证点:
- 总订单数正确处理
- 统计数据一致
13.3 并发撤单
测试函数: test_concurrent_cancel
流程:
1. 挂入400个买单
2. 收集所有order_id
3. 分成4组,4线程并发撤单
4. 验证撤单成功数 >= 350
验证点:
- 无重复撤单
- 无漏撤
- 线程安全
极端场景测试
14.1 价格极端波动
测试函数: test_extreme_price_range
测试范围:
#![allow(unused)] fn main() { // 极低价格 let low_price = 0.001; // 极高价格 let high_price = 9_999_999.99; }
验证点:
- 数值精度正确
- 无溢出
- 订单正常接受
14.2 大量撤单后重建
测试函数: test_orderbook_rebuild_after_mass_cancel
流程:
第一轮:
1. 挂入500个买单
2. 全部撤单
第二轮:
1. 重新挂入500个买单
2. 验证全部接受
验证点:
- 内存正确释放
- 订单ID继续递增
- 队列状态正确
14.3 混合工作负载
测试函数: test_mixed_workload_stress
线程分配:
下单线程 × 2: 300订单/线程 (买卖交替,价差1)
撮合线程 × 2: 200订单/线程 (统一价格)
模拟场景: 真实交易环境
14.4 超大批量提交
测试函数: test_massive_order_submission
参数:
#![allow(unused)] fn main() { let order_count = 50_000; }
验证点:
- 100%接受率
- 系统稳定
- 内存可控
测试执行指南
运行全部压力测试
# Debug模式 (带符号信息)
cargo test matching::engine::tests --lib
# Release模式 (性能测试)
cargo test matching::engine::tests --lib --release
# 显示输出
cargo test matching::engine::tests --lib --release -- --nocapture
运行特定类别测试
# 多标的测试
cargo test test_multi_instrument --lib --release -- --nocapture
# 吞吐量测试
cargo test test_throughput --lib --release -- --nocapture
# 延迟测试
cargo test test_latency --lib --release -- --nocapture
# 并发测试
cargo test test_concurrent --lib --release -- --nocapture
# 极端场景
cargo test test_extreme --lib --release -- --nocapture
cargo test test_massive --lib --release -- --nocapture
性能分析
# CPU profiling (Linux)
perf record cargo test test_throughput --release -- --nocapture
perf report
# 火焰图
cargo install flamegraph
cargo flamegraph --test test_throughput
# 内存分析
valgrind --tool=massif cargo test test_massive --release
问题排查
常见问题
1. 测试超时
症状: 测试运行时间过长
排查:
# 检查是否有死锁
RUST_BACKTRACE=1 cargo test test_name --lib -- --nocapture
解决: 检查锁顺序,避免循环等待
2. 内存溢出
症状: OOM 错误
排查:
# 限制内存
ulimit -v 4000000 # 4GB
cargo test test_massive --release
解决: 减少测试规模或优化内存使用
3. 并发测试失败
症状: 断言失败,数据不一致
排查:
# 多次运行查看是否稳定
for i in {1..10}; do
cargo test test_concurrent --release
done
解决: 检查原子操作和锁使用
调试技巧
#![allow(unused)] fn main() { // 添加调试输出 println!("[DEBUG] order_id={}, price={}, volume={}", id, price, volume); // 使用 env_logger RUST_LOG=debug cargo test test_name -- --nocapture // 条件断点 if order_id == 12345 { panic!("Debug point reached"); } }
压力测试检查清单
发布前检查
- 所有76个测试通过
- 吞吐量 > 100K orders/sec
- 延迟 P99 < 100μs
- 并发测试无数据竞争
- 50K订单测试100%接受率
- 内存使用稳定
- 无panic或崩溃
CI/CD 集成
# .github/workflows/test.yml
jobs:
stress-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run stress tests
run: |
cargo test matching::engine::tests --lib --release
timeout-minutes: 10