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

# 折腾 # · 2021-06-03

近期要上线一个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平台)说得云里雾里的。要么都是复制粘贴,重复内容一大堆,要么就是巴拉巴拉一大篇废话,一点实质性的东西都没有。

终究还是得自己摸索。先总结一下百度找到的几个原因和解决方案:

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

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

出现这个问题之后,我仔细分析了一下,可能是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。深层原因就有待深究了。

反正就是离谱。

如无特殊说明,本博所有文章均为博主原创。

如若转载,请注明出处:一木林多 - https://www.l5v.cn/archives/302/

评论

取消回复