记录一次离奇的java.io.IOException: Connection reset by peer报错解决方案

Blog原文:一木林多 - https://www.l5v.cn/archives/302/

问题来源

近期要上线一个Springboot项目,这里使用宝塔来部署这个项目。

在本地测试的时候,项目正常运行,没有任何报错,部署到Linux服务器上时,出现了这样离奇的问题:使用ip:8081访问项目时,可以正常访问,日志内没有任何报错。使用Nginx反向代理访问项目时,可以正常访问,但是日志内出现了报错:

2021-06-02 15:39:15.316 ERROR 19196 --- [io-7797-exec-91] c.x.j.a.c.resolver.WebExceptionResolver  : WebExceptionResolver:{}

org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
	at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:351) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
	at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:776) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
2021-06-02 15:39:15.318 ERROR 19196 --- [io-7797-exec-95] c.x.j.a.c.resolver.WebExceptionResolver  : WebExceptionResolver:{}

org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
	at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:351) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
	at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:776) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]

虽然在Nginx反向代理的场景下日志文件有报错信息,但是又不影响项目的正常运行。但是长此以往日志文件就会越积越多,能解决一个报错是一个报错。

经过两天的百度搜索,能得到一个统一的答案:什么网络异常、提前关闭,很多博客(特指某DN平台)说得云里雾里的。要么都是复制粘贴,重复内容一大堆,要么就是巴拉巴拉一大篇废话,一点实质性的东西都没有。

终究还是得自己摸索。

先总结一下百度找到的几个原因和解决方案:

Connection reset by peer 全解:https://www.cnblogs.com/crazymakercircle/p/14001467.html

Broken pipe错误终极解释:https://www.cnblogs.com/metoy/p/6565486.html


问题解决

林子大了什么鸟都有,代码写多了什么BUG都有。

出现这个问题之后,我仔细分析了一下,可能是Nginx反向代理配置的问题。参考百度的搜索结果,修改nginx缓存等等等乱七八糟的反向代理配置,毫无作用。

想到异常信息中出现了java.io.IOException这个字眼,我想会不会是因为某个文件请求出问题了。因此我在程序中加了个自定义异常处理的操作,捕获一下这个异常产生时所请求的URL和请求参数相关信息。

@ControllerAdvice
@Component
public class StackExceptionHandler implements HandlerExceptionResolver {
	// 实现HandlerExceptionResolver接口,重写resolveException方法
	// 通过httpServletRequest获取请求的相关信息
}

自定义异常处理做好之后,我又在反向代理的环境下访问了一次项目。自定义异常输出的内容大概是:

请求链接:xxxxx/xxx.png(是个图片)
异常名称:org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer

可见:由于静态资源的的未知原因,在反向代理的环境下访问静态资源,会报出这个异常,但是静态资源能正常加载。

解决方法:Nginx反向代理时,针对静态资源单独设置规则:

location ~ .*.(gif|jpg|png|html|htm|css|js|ico|swf|pdf|ttf|woff|woff2)$ {
	proxy_redirect off;
	proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header;
	proxy_set_header Host $host;
	proxy_set_header X-real-ip $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_pass http://localhost:8081;

	#Use Proxy Cache
	#Set Nginx Cache
	proxy_ignore_headers Set-Cookie Cache-Control expires;
	add_header Cache-Control no-cache;
	proxy_cache_valid  any 2d;
}

单独对静态资源下手后,问题解决,至此也没有再爆出这些错误。

至于问题出现的原因,有可能是因为nginx反向代理缓存配置的原因,也有可能是其他未知原因。但是能确定的是,反向代理过程中某一端提前关闭请求,才会造成java.io.IOException: Broken pipe。深层原因就有待深究了。

反正就是离谱。


版权声明:本文为jinhuang888原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。