系统稳定性保障:研发规约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)

维度 评估项
影响面 是否涉及多业务线?
回滚成本 回滚是否影响数据一致性?
相关推荐
Ray662 小时前
log4j2.xml配置文件详解
后端
Frank_zhou2 小时前
Easy-Es 架构设计详解
后端·elasticsearch
狗头大军之江苏分军3 小时前
Meta万人裁员亲历者自述:小扎尝到了降本的甜头
前端·后端·github
Jagger_3 小时前
SonarQube:提升代码质量的前后端解决方案
前端·后端·ai编程
在逃牛马3 小时前
【Uni-App+SSM 宠物项目实战】Day6:MP 实体类与 Mapper 生成
后端
remaindertime3 小时前
(九)Spring Cloud Alibaba 2023.x:微服务接口文档统一管理与聚合
后端·spring cloud·微服务
Barcke4 小时前
📘 初识 WebFlux
spring boot·后端·spring
JohnYan4 小时前
工作笔记 - 一个浏览器环境适用的类型转换工具
javascript·后端·设计模式
得物技术4 小时前
0基础带你精通Java对象序列化--以Hessian为例|得物技术
java·后端·编程语言