将一个 Spring Boot 项目从 4 分打磨到 6.5 分的生产级优化实录
项目背景
一个基于 Spring Boot 4.0.4 + MyBatis-Plus + PostgreSQL + Redis + Vue 3 的 C 语言作业批改与教学管理平台。功能很完整——AI 批改、知识库 RAG、热力图分析、QQ Bot 通知、教案生成——但离生产级差距不小。
初始评估:4.0 / 10.0
一、安全加固
1.1 JWT Token 泄露到日志
JwtAuthenticationFilter.java 中三处把 token 完整或部分打印到了日志:
1 | // 坏味道:完整打印 token |
修复:日志中只记录 path 和方法名,永远不输出 token 内容。同时发现该文件错误 import 了 reactor.netty.http.HttpConnectionLiveness.log,改用 Lombok 的 @Slf4j。
1.2 密钥硬编码
application.properties 中数据库密码、JWT Secret、OpenClaw API Key、OneBot Token 全部有弱默认值:
1 | # 修复前 |
修复:移除所有 fallback 默认值,改为 ${VAR} 无默认值。缺少环境变量启动即报错(fail fast)。本地开发值放入 application-local.properties(已 gitignore)。docker-compose.yml 密码改为 ${DB_PASS:?请设置 DB_PASS}。
二、高可用与容错
2.1 AI 服务熔断
所有 AI 调用经过 OpenClawServiceImpl,没有任何保护。AI 服务挂了会导致请求堆积、线程耗尽。
修复:引入 Resilience4j,对 chat() 和 streamChat() 加 @CircuitBreaker:
1 |
|
熔断配置:滑动窗口 10 次调用,>50% 失败自动熔断,30 秒后半开试探。
2.2 单点故障消除
| 组件 | 原状态 | 修复 |
|---|---|---|
| Redis | 无持久化,重启丢队列 | AOF + RDB 双持久化 |
| PostgreSQL | 无备份 | pgbackup 容器每日 pg_dump,保留 7 天 |
| App | 单实例 | Nginx 负载均衡 + --scale app=2 |
| App 关闭 | 直接 kill | server.shutdown=graceful,等待 30s |
| 无健康检查 | — | Actuator + Docker healthcheck |
2.3 Nginx 负载均衡
1 | upstream backend { |
启动多副本:docker-compose up -d --scale app=2
三、数据管理
3.1 Flyway 数据库迁移
项目中已经有 Flyway 命名的迁移文件(V2~V12),但根本没装 Flyway,全靠手工执行。
修复:
- 添加
flyway-core+flyway-database-postgresql依赖 schema.sql→V1__init_schema.sql,整理冲突文件(V7 重复、V20250510 非标准命名)- 已有数据库设
baseline-on-migrate=true+baseline-version=14,新库跑全量迁移 - 移除 docker-compose 中的
schema.sql挂载
3.2 N+1 查询优化
DashboardServiceImpl.getClassList() — 查 N 个班级,逐条查学生数:
1 | -- 修复前:1 + N 次查询 |
saveTeacherKnowledge() 逐条 insert 改为批量 insertBatch()。
四、文件存储
从本地磁盘升级为 S3 标准协议(AWS SDK v2),一套代码兼容所有对象存储:
1 | storage.type=local → 本地磁盘(开发) |
切生产环境只需改环境变量:
1 | STORAGE_TYPE=s3 |
代码零改动。
五、代码质量
5.1 状态魔法值 → 枚举
11 处 "COMPLETED"、"FAILED"、"PENDING"、"PROCESSING" 字符串统一定义为 SubmissionStatus 枚举:
1 |
|
5.2 JSON 提取去重
项目中 3 套 JSON 提取逻辑(ChatController.extractJsonFromMarkdown、StructuredOutputInvoker.extractJson、DashboardServiceImpl.extractFirstJson)合并为一个 JsonUtil.extractJson()。
5.3 Bucket4j API 升级
1 | // 旧(已过时) |
六、前端优化
6.1 Auth Store 修复
stores/auth.ts 的 login() 和 register() 完全不调 API——用邮箱前缀构造假用户。改为通过 request.ts(axios)调真实后端接口。
6.2 API 调用统一
项目中有两套 API 机制混用:
- axios(
request.ts)——少数组件在用 - raw
fetch()—— 6 个组件硬编码http://localhost:8080/api
统一为 axios,好处:
- 全局 baseURL 管控
- 自动带 token
- 401 自动跳转登录
- 统一错误拦截
修复了 LoginView、RegisterView、SubmissionView、TaskDetail、TaskManage、KnowledgeBase 共 6 个文件。
6.3 Markdown 渲染
AI 聊天页面从 1196 行缩到 310 行,手写的正则 Markdown 解析替换为 marked + highlight.js:
1 | marked.use(markedHighlight({ |
AI 回复现在支持代码高亮、表格、引用、列表等完整 Markdown 语法。
6.4 文件命名规范化
1 | PageOne.vue → StudentSubmit.vue |
成果
1 | 维度 优化前 优化后 |
改动统计
| 类别 | 数量 |
|---|---|
| 新增文件 | 12 个 |
| 修改文件 | 28 个 |
| 删除文件 | 3 个 |
| 新增依赖 | 6 个 |
下一步
测试覆盖率从 0 提升到 40%+,引入 CI/CD(GitHub Actions),补 Metrics + Tracing,可到 7.5~8.0 分。
生产级不是一蹴而就的——它是安全、高可用、可观测、代码规范、持续交付这些横切关注点的系统化积累。





