在高性能 Web 框架的研发中,我们经常面临一个尴尬的现实:无论业务逻辑跑得有多快,一旦进入数据库持久化环节,系统吞吐量就会遭遇“断崖式”下跌。
gzb one 拒绝接受这种平庸。通过 AsyncFactory 及其核心方法 saveAsync,我们重新定义了数据库操作的边界。
一、 核心设计理念:从“离散写入”到“流水线汇聚”
传统的 DAO 操作是同步的:HTTP 线程等待 JDBC 响应,JDBC 等待数据库事务。这种模式在高并发插入(如日志采集、监控埋点、高频流水)时,会导致大量的线程阻塞和数据库锁竞争。
gzb one 的异步逻辑并非简单的“丢给后台”,而是基于以下三大哲学:
1. 突破 I/O 硬性上限
saveAsync 的初衷不是为了释放 HTTP 线程,而是为了解耦业务频率与物理写入频率。将成千上万个离散的 SQL 请求汇聚到后台的 队列中,使系统具备了缓冲极端流量波峰的能力。
2. SQL 智能聚合(Aggregation)与批量下发
这是性能提升 5 到 30 倍的秘密。AsyncFactory 会根据 SQL 模板进行分类:
- 相同模板,统一处理:同一个 DAO 触发的 1000 次插入,在后台被聚合为一个
ConcurrentLinkedQueue。 - 批量提交(Batch Insert) :后台线程按
batchSize(如 500 条)进行executeBatch()提交。 - 收益:大幅减少了网络往返次数(RTT)和数据库服务器的事务开启/提交开销。
二、 源码级技术解析
1. 锁分离与极简队列架构
Java
public Map<String, ConcurrentLinkedQueue<Result>> cacheMap;
AsyncFactory 采用了 ConcurrentHashMap 配合 ConcurrentLinkedQueue。在写入(add)时,利用 ReentrantLock 保证队列初始化的原子性,但在后续高频入队时完全依赖无锁队列。这种设计确保了即便在每秒数万次 add 操作下,业务线程依然能实现“微秒级”返回。
2. 极其严苛的“原子性兜底”逻辑:rollbackFun
异步不代表不安全。在 execMapSql 中,如果批量提交失败(例如其中一条数据导致了主键冲突),AsyncFactory 不会丢弃其余数据:
- 整体回滚:立刻执行
connection.rollback()。 - 逐条退化执行:将批量任务拆解,逐条进行同步执行。
- 精准回调:成功的触发
success回调,失败的触发fail回调。这种“批量进,单条退化”的机制,保证了数据的最终一致性。
3. 闭环的回调机制(Callback)
Java
sysFileDao.saveAsync(sysFile, () -> {
// 失败补偿
}, () -> {
// 成功处理
});
通过 Runnable 接口,开发者可以在异步任务结束后,自由引用当前作用域的上下文信息(如用户信息、订单对象)。这为异步操作后的“数据补救”或“前端通知”提供了完美的支撑。
三、 实战:为什么采用 dao.saveAsync()?
在 gzb one 中,代码示例展示了极简的调用方式:
Java
@PostMapping("test")
public Object test(SysUsersDao sysUsersDao, GzbJson gzbJson) {
SysUsers user = new SysUsers().setSysUsersAcc("gzb_666");
// 异步保存,立即返回 OK
sysUsersDao.saveAsync(user, () -> {
log.e("数据持久化最终失败,开始执行业务补偿", user);
});
return gzbJson.success("任务已受理");
}
这种方式解决的痛点:
- 消除延迟:用户请求不再等待磁盘 I/O。
- 保护数据库:通过后台线程数(
threadNum)和等待时间(batchAwait),框架实际上对数据库起到了“限流保护”的作用,防止瞬时并发冲垮数据库连接池。 - 自适应压力:当队列积压时,后台线程会自动根据
batchSize进行满载运行;当流量小时,则进入sleep状态节省资源。
四、 什么时候用异步?
虽然异步很强,但 gzb one 建议遵循以下原则:
- 推荐场景:日志、埋点、统计、非关键业务流、高频状态更新。
- 慎用场景:对严格原子性和实时可见性要求极高的金融账务操作(例如扣款后立即查询余额)。
总结
gzb one 的 AsyncFactory 是对底层资源榨取到极致的表现。它不只是一个异步工具,更是一个智能的 I/O 调度中心。
它让开发者能够以最简单的代码,享受到工业级高并发系统才有的批量聚合写入能力。在 gzb one 的世界里,数据库再也不是拖慢系统的“后腿”。
github:github.com/qq129736888…
gitee:gitee.com/gzb001001/g…