教学系统后端优化实录:Java 21 虚拟线程 + Spring AI 2.0 + Redis Lua 限流 AOP
背景
对一个基于 Spring Boot 4.0 + MyBatis-Plus + PostgreSQL 的教学管理系统进行技术升级,参考了 spring-ai 企业级项目的架构模式,完成了三项核心优化。
一、Java 17 → 21 + 虚拟线程
改动
pom.xml
1 | <java.version>17</java.version> → <java.version>21</java.version> |
application.properties
1 | spring.threads.virtual.enabled=true |
原理
Spring Boot 4.0 原生支持 Java 21 虚拟线程(Project Loom)。开启后,Tomcat 请求处理线程、@Async 方法、WebFlux 调度线程全部切换为虚拟线程。
虚拟线程由 JVM 管理,不绑定 OS 线程,I/O 阻塞时自动让出 CPU。对于 AI API 调用、数据库查询、Redis 操作等 I/O 密集型场景,并发吞吐显著提升。
兼容性
现有 pom.xml 中所有依赖(MyBatis-Plus 3.5.15、Redisson 3.29.0、DJL 0.28.0 等)均已支持 Java 21,无需升级。
二、Spring AI 2.0 替换手动 HTTP 调用
改前
1 | // 手动构造 HTTP 请求 → WebClient 发送 → 手动解析 JSON → 手动处理 SSE |
代码量:约 200 行,包含请求构造、SSE 解析、Agent 路由、流式包装。
改后
1 | // ChatClient 链式调用,一行搞定 |
代码量:约 80 行。流式响应、结构化输出、重试容错全部由框架处理。
关键发现
OpenClaw Gateway 原生支持 /v1/chat/completions 端点(默认关闭,需在 config 中启用),与 Spring AI 2.0 的 OpenAI 兼容模式完全对齐。Agent 路由通过 model 字段实现,不再需要自定义 Header。
涉及文件
pom.xml:添加spring-ai-starter-model-openaiapplication.properties:Spring AI 配置替换原 OpenClaw HTTP 配置OpenClawServiceImpl.java:ChatClient 重写(200 行 → 80 行)openclaw.json:启用chatCompletions端点- 删除
OpenClawConfig.java、OpenResponsesResponse.java(Spring AI 自动配置接管)
三、Redis Lua 滑动窗口限流 AOP
架构
1 | @RateLimit 注解 → AOP 切面拦截 → Redis Lua 原子执行 |
实现细节
1. 注解层
1 |
|
2. AOP 切面
1 |
|
3. Lua 滑动窗口脚本
1 | -- 清理过期记录 |
为什么用 Lua + Sorted Set
- 原子性:ZREMRANGEBYSCORE → ZCARD → ZADD 三步必须原子完成,否则并发时计数不准
- 滑动窗口:Sorted Set 按时间戳 score 精确清理过期记录,避免固定窗口的边界突刺问题
- Hash Tag:Key 中的
{ClassName:method}确保同一方法的多维度 Key 落在同一 Redis Cluster Slot
涉及文件
common/annotation/RateLimit.java— 注解定义common/aspect/RateLimitAspect.java— AOP 切面common/exception/RateLimitExceededException.java— 限流异常resources/scripts/rate_limit.lua— Lua 脚本ErrorCode.java— 新增RATE_LIMIT_EXCEEDED(429)ChatController.java— 示例注解
四、后续优化方向
| 优先级 | 项目 | 价值说明 |
|---|---|---|
| 🔴 高 | Docker 多服务编排 | 一键部署 PG + Redis + App,面向学校交付 |
| 🔴 高 | Flyway 数据库迁移 | SQL 版本化管理,替代手动建表 |
| 🟡 中 | iText PDF 报告导出 | 作业批改结果导出 PDF 给学生 |
| 🟡 中 | 单元/集成测试 | Dashboard 统计逻辑复杂,该有测试兜底 |
| 🟢 低 | MinIO 对象存储 | 替换本地磁盘存储文件 |
五、技术栈总览
| 类别 | 技术 |
|---|---|
| 框架 | Spring Boot 4.0、Spring AI 2.0、Spring Security、Spring AOP |
| ORM | MyBatis-Plus |
| 数据库 | PostgreSQL + pgvector(向量检索) |
| 缓存 | Redis(Redisson 客户端) |
| 消息队列 | Redis Stream |
| AI 集成 | Spring AI ChatClient(OpenClaw Gateway) |
| Embedding | DJL ONNX Runtime(bge-small-zh-v1.5 本地推理) |
| 文档解析 | Apache Tika |
| 限流 | Redis Lua 滑动窗口 + AOP |
| Java | Java 21 + 虚拟线程 |
| 文档 | SpringDoc OpenAPI |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 LKL-ZREO!





