系统稳定性保障:研发规约V1.0

数据库层面

数据描述 案例 备注信息
禁止对大表在高峰期建索引 - xxx_log(2000w+)对 xxx_log 表建索引,导致表锁超过2min,严重影响业务,所有新增日志被阻塞
禁止对大表在高峰期进行类型变更 - message_xxx(500w+)ALTER TABLE message_xxxMODIFY COLUMN error longtext NULL COMMENT '错误'影响消息发送,业务严重阻塞 // 其他线程获取连接超时Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: master - Connection is not available, request timed out after 30000ms.
采用默认连接池 连接池过小,并发高时连接快速被打满,导致整个生产系统变慢 如HikariCP默认maxPoolSize=10
一个没有索引的UPDATEDELETE语句(WHERE条件无法命中索引),会对全表进行扫描和锁定,等效于一次锁表操作 UPDATE huge_table SET status = 1 WHERE create_time > '2023-01-01';(如果create_time无索引)
未加索引的模糊查询引发全表扫描 SELECT * FROM order_log WHERE mobile LIKE '138%';
大批量数据删除或更新时未分批次操作(同上) DELETE FROM operation_log WHERE create_time < '2022-01-01';(无索引或即使有索引也可能产生巨大事务),单事务过大(删除5000w行)
排序字段没有索引导致分页数据重复 order by 字段, 字段没有索引,导致分页查询时出现数据重复情况。分页数据不稳定

避免高峰期变更,工具化安全改表

在高并发、大数据量场景下,数据库是系统的瓶颈点之一。尤其当单表数据量超过百万级(如500万+),任何DDL(数据定义语言)操作都可能引发锁表、主从延迟、连接池耗尽等严重问题

指标 风险阈值
单表行数 > 500万视为"大表"
DDL执行时间 > 30秒需评估影响
锁等待超时 lock_wait_timeout > 60s 视为高危

代码层面

jdk8 注意事项

相关API 具体描述
Collections.sort(list) list 含 null 元素 → NPE,推荐使用 Comparator.nullsFirst()
Collectors.toMap 重复值 Duplicate key 错误.....value 的 function 计算结果 null 引发 NPE
parallelStream 并行流 ThreadLocal#get() 为 null可能导致非线程安全类出现并发异常
stream#sort 排序 排序字段为 null,引发 NPE,多字段排序时此类问题尤为常见
java.util.Optional#get/of of 入参为 null,引发 NPE; get() 返回值为 null 时可能引发异常....

常见编码

相关API 具体描述
资源未关闭导致内存泄漏或文件句柄耗尽 // 使用 try-with-resources(推荐)。 try (FileInputStream fis = new FileInputStream("file.txt"); BufferedReader br = new BufferedReader(new InputStreamReader(fis))) { // 自动关闭 } catch (IOException e) { e.printStackTrace(); }
吞掉异常 try {riskyOperation();} catch (Exception e) {// 吞掉异常,导致问题被隐藏,极难排查}
ThreadLocal 需要 remove try {UserContext.setUser(user);// 处理业务} finally {UserContext.userHolder.remove(); // 必须 remove!}ThreadLocalMap 使用 WeakReference 作为 key,但 value 是强引用。key 被回收后变成 null,但 value 仍存在 → "弱引用 key + 强引用 value" 导致内存泄漏
Arrays.asList() 返回的 List 不能修改 List list = Arrays.asList("a", "b", "c");list.add("d"); // UnsupportedOperationExceptionlist.remove(0); // 同样异常Arrays.asList() 返回的是 Arrays 的内部类 ArrayList(注意不是 java.util.ArrayList),它不支持增删,只支持 set()
BigDecimal 的正确使用 用于金融计算时,必须使用 BigDecimal,且避免使用 double 构造函数BigDecimal price = new BigDecimal(0.58); // 可能出现精度问题BigDecimal price = new BigDecimal("0.58"); // 使用字符串构造
建议方法不要返回 null 值 使用
NoSuchMethodError 不属于 Exception,而是 Error; 在一些反射时候,捕获catch 要留意 属于 Error 类型,注意 catch Throwable

空值检查与防御性编程

相关API 描述
使用 Optional / Object.isNull 做好空值控制和防御性编程

边界值

相关API 描述
while(true)/for(;;) - 一定要注意异常的情况,最终导致不能退出

多线程

相关API 描述
parallelStream 使用线程不安全的API,比如 ArrayList、ThreadLocal#get等
优雅关闭 对于重要任务,未进行优雅关闭
CompletableFuture 设置最大等待时间处理好异常(exceptionally方法来处理异常情况)
CountDownLatch 保证 countDown 一定会被执行(注意异常,放在 finally 方法中)设置最大等待时间防止其中一个操作阻塞或者出现异常,导致整个操作链死锁

事务失效场景

  1. 在非public方法上用@Transactional不会报错,但也不会生效。就跟没写一样
  2. 在类内部调用事务方法,@Transactional不生效
  3. 把异常catch住处理掉了,没往上抛,@Transactional不生效
  4. 方法抛出的异常和rollbackFor指定的异常不匹配(rollbackFor不写的话默认RuntimeException)
  5. 新开线程执行DML,@Transactional不生效; (子线程抛出的异常父线程捕获不到,两个线程不在同一事务里面)

发布影响

发布评估 影响面 具体描述
基建需求,如果涉及各业务线,需要各个业务线配合的务必提前沟通,不能因流程繁琐或主观认为影响小而跳过沟通环节 20250901 数据权限上线,导致部分GDS接口没有权限。 可以业务线配合,也可以延期,但是不能存在问题提前业务线验证,可最大程度避免问题
重点需求,线下先观察 20250820 数据权限上线,周末集中在 dev/tst/pre 验证,问题未被暴露,上线引发问题 预留一定的时间,用来做观察

发布评估清单(Checklist)

维度 评估项
影响面 是否涉及多业务线?
回滚成本 回滚是否影响数据一致性?
相关推荐
计算机程序设计小李同学36 分钟前
动漫之家系统设计与实现
java·spring boot·后端·web安全
布列瑟农的星空1 小时前
SSE与流式传输(Streamable HTTP)
前端·后端
开心就好20251 小时前
使用 HBuilder 上架 iOS 应用时常见的问题与应对方式
后端
开心猴爷1 小时前
Swift IPA 混淆在工程实践中的方式,分析仅依赖源码层混淆的局限性
后端
用户4099322502122 小时前
Vue3 v-if与v-show:销毁还是隐藏,如何抉择?
前端·vue.js·后端
黄俊懿2 小时前
【深入理解SpringCloud微服务】Seata(AT模式)源码解析——全局事务的回滚
java·后端·spring·spring cloud·微服务·架构·架构师
Java编程爱好者2 小时前
SpringBoot启动太慢?几个优化技巧
后端
喷火龙8号2 小时前
修复 Hertz + OpenTelemetry 链路追踪中的数据竞争问题
后端
JIngJaneIL2 小时前
基于springboot + vue健康管理系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·后端
程序员小胖2 小时前
每天一道面试题之架构篇|Java 热部署插件化架构设计
后端