本文最后更新于 3 分钟前,文中所描述的信息可能已发生改变。
项目漏洞
1. 全局消息定序机制:
问题:依赖 SequenceID 和 PreviousID 的时序假设
如果网络抖动或消息丢失,PreviousID 可能无法及时对齐,导致消息阻塞或顺序错乱。
如果一个消息丢了但没有重发机制,可能造成后续消息全部失效。
建议:
引入 Paxos/Raft 等共识协议来保证多节点顺序一致性。
或者实现类似 Kafka 的 Partition + Offset 管理方式,并配合 ACK + 重试机制防丢失。
2. 基于内存的交易引擎:
问题:数据落盘是异步的,如果崩溃发生在持久化前,会存在数据丢失风险
建议:
引入 Write-Ahead Log(预写式日志 WAL)机制。
或使用高性能本地持久化技术(如 Chronicle Queue、Disruptor RingBuffer + mmap 文件落盘)。
3. 撮合引擎(TreeMap 双结构):
问题:TreeMap 本身是线程不安全的;高并发下可能存在数据竞争
建议:
引入
ConcurrentSkipListMap或使用读写锁来保护撮合核心逻辑。或使用更高性能的撮合结构,如 Price-Level Queue(价格级队列),配合 price → list 结构。
4. Redis + Lua 脚本更新行情:
问题:Redis 单线程,Lua 执行过程中阻塞所有其他命令;高频行情下可能成为瓶颈
建议:
限制 Lua 脚本的逻辑复杂度和执行时间。
拆分行情粒度,按品种分散到多个 Redis 实例。
5. Vert.x WebSocket 推送系统:
问题:WebSocket 长连接需要心跳维持;如果客户端断开无检测机制,会占用资源
建议:
每隔 X 秒发 Ping/Pong 心跳。
检测 stale 连接并及时关闭。
量化指标与测试方式设计
| 模块 | 指标 | 测试方式 |
|---|---|---|
| 全局消息定序 | - 顺序一致性 - 消息无丢失率(≦0.01%) | - 构造 1000 万条消息流,插入乱序包,验证是否顺序输出 - 故障注入(kill publisher),观察恢复后 ID 连续性 |
| 内存撮合引擎 | - 撮合 TPS ≥ 10W/s - 撮合延迟 P99 ≦ 2ms | - 用 JMH 构造 OrderMatchBenchmark,模拟百万用户下单 - profile GC 情况,检测内存访问与锁竞争 |
| 数据可靠性(异步持久化) | - 崩溃恢复数据一致性 > 99.999% | - 在交易高峰期强制 kill 掉 engine 进程,重新拉起后比对 snapshot + WAL 的重放结果 |
| API 延迟 | - REST API 响应延迟 P99 ≦ 20ms - 异常请求错误率 ≦ 0.1% | - 使用 Gatling/Locust 进行 10 万并发压测,持续 10 分钟 - 模拟超时、错误参数等请求注入 |
| 行情更新与广播 | - Redis 更新延迟 ≦ 5ms - 广播延迟 P99 ≦ 10ms | - 统计每个 Lua 脚本的执行时间(INFO 命令 + latency monitor) - 模拟 1 万客户端,用 WebSocketClient 采样接收时间戳差 |
| 推送系统并发能力 | - 支持连接数 ≥ 10 万 - 心跳丢失率 ≦ 0.1% | - 使用 Netty/Vert.x 压测工具模拟 WebSocket 客户端并发连接 - 启动 TCP Dump 检测连接是否成功完成三次握手并保持活跃 |