记录一次 spingboot的偶发性502 bad gateway异常
我们项目组的一个小型api项目上线后,、
下游对接的项目组给我们反馈, 一天会有几百次调用不成功, 返回的是HTTP 502 BAD GATEWAY错误
出现这个问题第一时间想到的是nginx的反向代理出了问题,经过查找资料,找了很多文献和更改后发现没有用
我们自己写了一个小脚本,一直请求发现,在请求量小的时候没有问题,请求量一大就开始抛502异常,绕过nginx直接请求tomcat一样会有502异常
更换内置tomcat版本后依然一样
现在就确认了 是业务代码问题 更改日志级别为TRACE打印出所有日志
最后翻到了,在jvm触发GC的时候, tomcat的线程池的OutputStream会被关闭,这tm就奇怪了啊,GC为什么会关闭线程池暂存的OutputStream
在堆栈信息中找到了一个关键点, 是ImageOutputStream被关闭的时候触发了Finalize方法(关于Finalize这里就不做解释了,自行搜索即可)
Finalize关闭了tomcat暂存的OutputStream,导致了502
在代码里面找,哪里有用到了ImageOutputStream相关代码
QrCodeUtil.generate("123",255,255, "png", response.getOutputStream());
这句代码作用是帮助前端生成二维码,直接写入outputSteam这样前端可以直接在img标签是用,非常方便
看到这里大家应该都明白了,在写入后ImageIo相关的Stream就没有用了, 在GC的时候被销毁,ImageStream被销毁的时候触发Finalize方法,关闭相关输出的outputStream,导致了tomcat暂存的流被关闭,这个时候如果这个流被复用就会触发502
改成Base64返回,或者IoUtils.copy进行写入就好了