记录一下最近发现的springboot和spring中的两个小问题
springboot覆盖netty内存检查等级
从下图可以看出netty的ResourceLeakDetector的level在不设置jvm参数时默认是simple,也就是跟踪检查1%的byteBuf。simple是权衡性能和检查内存泄漏功能的完美选项,所以绝大多数场景开发人员都不会主动更改该默认值,直接使用默认的simple策略
NettyAutoConfiguration和NettyProperties从springboot2.5.0引入,暂时只有一个功能就是设置netty检查内存泄漏的策略。由于NettyProperties中leakDetection默认是disable,所以会关闭netty的内存检查
由于NettyAutoConfiguration默认就会关闭netty的内存检查并且没有任何提示,会给同时使用netty和springboot的用户造成困惑。比如及时看到了下文打印的netty debug日志,却发现依然无法检查内存
- - 2021-06-17 23:44:33.928 DEBUG 17072 --- [ main] io.netty.util.ResourceLeakDetector : -Dio.netty.leakDetection.level: simple
而且NettyProperties中单独引入了额外LeakDetection的枚举和ResourceLeakDetector.Level枚举做映射。这就造成了同一个东西在两处维护,一旦后续一个有改动另一个就要跟着改
根据上面分析的内容提交了如下pr:
详见:https://github.com/spring-projects/spring-boot/pull/26958
1、将NettyProperties的leakDetection默认值为null。这样只有用户主动设置了spring.netty.leak-detection,NettyAutoConfiguration才会去设置内存检查
2、删除NettyProperties.LeakDetection枚举,直接使用ResourceLeakDetector.Level,避免后续两头维护
3、去除additional-spring-configuration-metadata.json中spring.netty.leak-detection的默认值显示
4、在NettyAutoConfigurationTests中增加单侧保证,不设置spring.netty.leak-detection时不会更改netty的内存检查策略,设置的时候正确的改变netty的内存检查策略
spring执行初始化sql重复打印警告日志
工程中设置了初始化数据库的sql,每次工程启动都会执行,只有当表不存在时才会新建表
但是在日志中发现虽然确实执行了两个sql,但是总共打印出了三条SQLWarning日志
- - 2021-06-20 23:42:08.673 DEBUG 38614 --- [main] o.s.jdbc.datasource.init.ScriptUtils : 0 returned as update count for SQL: CREATE TABLE IF NOT EXISTS `lock_info` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', PRIMARY KEY (`id`))
排查发现执行初始化sql的工具类ScriptUtils中对所有sql都会使用同一个statement,并且每次执行后并不会清空warningLog,也就造成了warnLog的累计
所以应该在stmt.getWarnings()后调用stmt.clearWarnings()或者干脆每个sql都重新创建一个statement执行
详见:https://github.com/spring-projects/spring-framework/pull/27084