下载文件出现异常:org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe

最近写了一些接口提供给第三方对接,再做一层 nginx 代理出去,其中有这样两个接口,一个是文件上传接口,一个是文件下载接口,文件上传接口没有问题,但是文件下载接口一直报这个一下这个错误,用 postman 下载不是在转圈就是没有返回:

Caused by: java.io.IOException: Broken pipe
	at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
	at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
	at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
	at sun.nio.ch.IOUtil.write(IOUtil.java:65)
	at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:469)
	at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:142)
	at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:118)
	at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:167)
	at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1360)
	at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:718)
	at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:538)
	at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:482)
	at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:632)
	at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:127)
	at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:229)
	at org.apache.coyote.Response.doWrite(Response.java:614)
	at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:358)

而我的主要代码是:

public void downloadFile(HttpServletResponse response, String filePath) {
   try {
       // 获取文件存入 inputStream 中,我们自己的业务
       ServletOutputStream output = response.getOutputStream();

       byte[] buffer = new byte[1024];
       int len = inputStream.read(buffer);
       while (len != -1) {
           output.write(buffer, 0, len);
           len = inputStream.read(buffer);
       }
       output.flush();
       output.close();
   } catch (Exception e) {
       e.printStackTrace();
       System.out.println("下载文件出错:" + e.getMessage());
   }
   return;
}

其中一直在这一行报错:

output.write(buffer, 0, len);

我一直以为是 response 断了,所以显示管道断开的异常,因为这个项目是部署在 tomcat9 服务器上,所以我往 tomcat 方面百度了很久,也没找到问题,接着我修改了代码,修改 inputStream 写入 response 代码,以为是缺少了什么细节,不仅还是报异常,有时候还多了下面这个错误:

org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
	at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:371)
	at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:845)
	at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:750)
	at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:406)
	at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:384)
	at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)

这让我抓狂,最后请教了我的大佬同事,开始他的思路跟我一样,也是以为是写入问题,最后我们想起我们还做了 nginx 代理,想着去看一下 nginx 日志,发现还真的有问题, nginx 的 error.log 日志报了这个错误:

upstream sent invalid chunked response while reading upstream

然后我们就终于找到了问题的所在了,原来是代码没问题,但是 nginx 转发的时候出问题了,百度后发现是需要再 nginx 的 location 模块里面配置 proxy_http_version 1.1
添加配置
原因是 nginx 在代理是默认 http 版本为 1.0,由于文件的下载需要使用功能分块传递,但 http1.0 是不支持这个特性的,所以 nginx 需要配置为 1.1 版本, 否则无法进行转发。但我看到其他服务没有配置这个项目也可以转发下载,我就很奇怪了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

六月的北回归线

砸我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值