记一次springboot自动重启问题排查思维过程
先说结论
springboot有个插件dev-tool, 这个插件会自动检测classpath, 如果有代码变更会重启发布有可能引起重新启动服务, 我们的情况正好是往classpath中写入csv,zip等文件引起的.
所以,尽量不要把classpath下当做临时文件的输出目录,在服务器单独开辟独立空间,统一管理.
起因
一个研发小哥哥使用springboot框架开发一个生成文件及压缩文件的功能,开发过程中,一旦写入文件或者压缩文件时,会突然提示数据源session is closed,然后springboot就开始重启,调试了两天没搞定,于是咨询我.
表象
一旦写入一部分文件或者生成zip压缩文件时:
- 提示session is closed
- springboot开始重启
排查过程
1. 排查双数据源配置问题
由于首先提示session is closed, 由于小哥哥刚好配置了双数据源,之前是单数据源, 所以刚开始排查重点目标集中在是不是由于数据源没配置好, 导致关闭进而又引起了springboot重启.
当然通过我们的后见之明偏误的时候,会觉得这个推论站不住脚,因为即使数据源配置有问题,session is closed也不至于引起springboot重启.
之所以当时会在这块花时间我觉得有俩原因:
- springboot相关知识性缺失
- 对自己的推理不够信服
知识性缺失就是说对springboot和数据源配置不够了解.进而导致自己不敢肯定自己的推论.
排查内存使用
由于服务重启, 然后我们的场景又有读取一定量数据,写文件等操作. 所以很容易考虑到是内存占用导致的原因.遂打开垃圾回收机制,查看日志.
现象描述:
- 没有OOM相关错误
- gc日志有一些,young gc , 启动时有full gc, 看数据都是正常
此处需要的知识点是:
- OOM会导致进程挂掉,但是并不会重启
- 要知道young gc, full gc多久算频繁, 及相关耗时阈值算不正常
基于上述情况分析,我们应该把关注点放到springboot本身上, springboot本身是不是有什么机制会自己重启?
- 谁导致的重启
- 什么情况下会重启
G一下很容得出结论, springboot有一种dev-tool的工具会自动检测代码是否变更然后自动发布, 任何写入到classpath(当然有一些例外的文件夹,具体看它描述) 都会认为是代码变更,此时触发它的重新发布机制,所以接下来你需要做的就是弄清什么情况下热部署而不重启, 什么情况下需要重启服务.
原因:我实现文件上传功能,而文件上传到项目的classpath下,导致springboot热部署启动而项目重启,所以热部署应用一定要谨慎!
注意:本文归作者所有,未经作者允许,不得转载