诸葛亮会议个人
技术栈:Java Servlet 8.0 + MySQL 8.0 + Tomcat 9.0
一、核心成果与痛点拆解
成功交付模块
任务管理API
实现POST /api/task核心接口:
// 关键代码:任务创建入库
String sql = "INSERT INTO task (name, class_id, deadline) VALUES (?, ?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, request.getParameter("name"));
pstmt.setInt(2, Integer.parseInt(request.getParameter("class_id")));
pstmt.setTimestamp(3, new Timestamp(System.currentTimeMillis() + 2436001000)); // 默认1天有效期
pstmt.executeUpdate();
创新点:采用预编译语句防SQL注入,硬编码默认时长避免空值异常
成绩提交事务处理
解决高并发场景下数据错乱:
java
try {
conn.setAutoCommit(false); // 关闭自动提交
// 1. 插入成绩记录
String sql1 = "INSERT INTO score (user_id, task_id, points) VALUES (?,?,?)";
// 2. 更新任务完成数
String sql2 = "UPDATE task SET complete_count = complete_count+1 WHERE id=?";
// 批量执行
executeBatch(conn, Arrays.asList(sql1, sql2));
conn.commit(); // 原子提交
} catch (SQLException e) {
conn.rollback(); // 回滚
throw new ServletException("事务失败: " + e.getMessage());
}
效果:40人并发测试时错误率从35%降至0
生产环境部署
自主搭建Linux(CentOS 7) + Tomcat + MySQL环境
编写自动化启动脚本:
bash
!/bin/bash
nohup $TOMCAT_HOME/bin/startup.sh & # 后台启动Tomcat
systemctl restart mysqld # 重启MySQL
未完成任务分析
功能 失败原因 技术难点
实时排行榜 事务处理占时超预估 需ORDER BY+LIMIT高频查询优化
批量分配班级 循环逻辑报错后放弃 班级ID数组解析异常处理不足
最痛技术教训
事务漏用引发生产事故:
场景复现:首次上线时20人同时提交成绩,8人收到“提交成功”但数据丢失
排查过程:
检查MySQL日志发现锁超时错误:Lock wait timeout exceeded
复盘代码:未启用事务导致部分UPDATE语句独占锁
解决方案:
// 错误写法(无事务)
stmt.executeUpdate("UPDATE score SET points=100 WHERE user_id=1"); // 可能阻塞
// 修正方案
conn.setAutoCommit(false); // 开启事务
PreparedStatement pstmt = conn.prepareStatement(...); // 预编译
pstmt.executeUpdate();
conn.commit(); // 统一提交
二、关键问题技术溯源
- 任务分配API延迟4天
问题本质:批量处理逻辑死循环
// 错误代码:未处理数组越界
String[] classIds = request.getParameterValues("class_ids");
for (int i=0; i<=classIds.length; i++) { // 应为 i<classIds.length
int classId = Integer.parseInt(classIds[i]); // i=length时越界
}
调试血泪史:
Day1:认为Servlet参数获取错误
Day3:发现越界异常被全局catch吞没
改进方案:
伪代码先行验证:
text
输入:class_ids=[1,2,3]
预期:生成3个任务
实际:循环4次(i=0,1,2,3) - 紧急暂停功能熬夜事件
技术债清单:
需求 开发耗时 引发问题
加pause_flag 2小时 简单
状态同步机制 6小时 前端轮询接口压力激增300%
架构缺陷:
原方案:前端每2秒请求GET /api/task_status
后果:50学生并发时QPS达25,Tomcat线程池爆满 - 部署权限灾难
故障链分析:
图表
代码
救命操作:
凌晨2点远程连生产环境补救
GRANT INSERT, UPDATE ON emergency.* TO 'app_user'@'%';
FLUSH PRIVILEGES;
三、血泪经验体系化总结
事务处理四原则
写操作必加事务:哪怕只有1条UPDATE
事务范围最小化:
// 反例:事务包含耗时逻辑
conn.setAutoCommit(false);
updateScores(); // 1.快速更新
sendEmailReport(); // 2.耗时操作 → 导致锁膨胀
conn.commit();
隔离级别显式声明:
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); // 避免脏读
回滚日志必打印:
java
catch (SQLException e) {
logger.error("事务回滚: task_id={}", taskId, e); // 关键:记录错误数据标识
conn.rollback();
}
接口设计三大铁律
原则 反例 正例
单一职责 /api/task?action=create&delete=1 拆分为POST /api/task 和 DELETE /api/task
参数扁平化 class_ids[]=1&class_ids[]=2 class_ids=1,2
状态码规范 错误全返回200 400参数错误,500服务异常
时间估算公式(学生版)
text
实际耗时 = 理论耗时 × 2 + 考试压力系数
其中:
理论耗时:无干扰条件下的理想值
考试压力系数:
考试周:+3天
作业密集期:+1.5天
四、未来行动计划表
技术提升路线
技能 学习资源 验收标准
Spring Boot 尚硅谷SpringBoot3视频课 重构任务API并实现Swagger文档
JMeter压测 使用JMeter模拟100并发 找出成绩接口的TPS瓶颈点
SQL优化 《MySQL性能调优实践》 explain分析慢查询
协作规范
接口文档强制化
要求前端提供字段示例:
json
// 请求示例
{
"task_name": "3号楼火灾演练",
"deadline": "2025-06-20 14:00:00"
}
数据库变更审批流
图表
代码
个人开发纪律
每日事务检查清单
所有UPDATE/DELETE语句是否包含在事务中
预编译语句是否使用setString()而非拼接
生产环境部署包
必含文件:
权限检查.sql(GRANT语句脚本)
tomcat_restart.sh(进程守护脚本)
终极忠告(自刻桌面壁纸版)
事务是后端的第一道呼吸:没有事务的写操作如同裸奔
简单即正义:宁可写10个简单接口,不做1个万能接口
生产环境敬畏心:
bash
每次登录服务器前默念
rm -rf /* # 此命令永不可执行!
—— 于凌晨三点修复生产故障的后端人