org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe问题探究

简介: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe问题探究

背景

今天下午遇到同事求助,说是服务端出现了好几个java.io.IOException: Broken pipe这样的异常,让我帮忙看一下,这个问题对于我们做服务端开发的技术人员是很容易遇到的,特此记录一下。

探究

问题堆栈

org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
  at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:356)
  at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:825)
  at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:730)
  at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:391)
  at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:369)
  at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
  at org.springframework.session.web.http.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(  OnCommittedResponseWrapper.java:620)
  at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write( OnCommittedResponseWrapper.java:639)
  at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write( OnCommittedResponseWrapper.java:639)
  at com.fasterxml.jackson.core.json.UTF8JsonGenerator._flushBuffer(UTF8JsonGenerator.java:2085)
  at com.fasterxml.jackson.core.json.UTF8JsonGenerator._writeBytes(UTF8JsonGenerator.java:1173)
  at com.fasterxml.jackson.core.json.UTF8JsonGenerator.writeFieldName(UTF8JsonGenerator.java:256)
  at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:725)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
  at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
  at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
  at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
  at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
  at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
  at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
  at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
  at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
  at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
  at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
  at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
  at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396)
  at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913)
  at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(  AbstractJackson2HttpMessageConverter.java:286)
  at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:102)
  at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(  AbstractMessageConverterMethodProcessor.java:272)
  at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(  RequestResponseBodyMethodProcessor.java:180)
  at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue( HandlerMethodReturnValueHandlerComposite.java:82)
  at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle( ServletInvocableHandlerMethod.java:119)
  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(  RequestMappingHandlerAdapter.java:877)
  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal( RequestMappingHandlerAdapter.java:783)
  at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
  at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
  at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
  at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
  at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)  

着重关注点

堆栈信息中有一行比较关键,在OutputBuffer :: realWriteBytes这个方法中出现了异常,在方法内部抛出了ClientAbortException: 

at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:356)

OutputBuffer#realWriteBytes

/**
 * Sends the buffer data to the client output, checking the
 * state of Response and calling the right interceptors.
 *
 * @param buf the ByteBuffer to be written to the response
 *
 * @throws IOException An underlying IOException occurred
 */
public void realWriteBytes(ByteBuffer buf) throws IOException {
    if (closed) {
        return;
    }
    if (coyoteResponse == null) {
        return;
    }
    // If we really have something to write
    if (buf.remaining() > 0) {
        // real write to the adapter
        try {
            coyoteResponse.doWrite(buf);
        } catch (IOException e) {
            // An IOException on a write is almost always due to
            // the remote client aborting the request. Wrap this
            // so that it can be handled better by the error dispatcher.
            throw new ClientAbortException(e);
        }
    }
}

在上面的代码中,调用coyoteResponse.doWrite(buf);方法时,会抛出ClientAbortException异常

我们仔细阅读以下上述注释:

An IOException on a write is almost always due to the remote client aborting the request.
Wrap this so that it can be handled better by the error dispatcher.
进行写操作时出现的IOException几乎总是由于远程客户端中止请求而导致的。将其包装起来,以便错误调度程序可以更好地处理它。 

结论

有位大神将此问题对应的流程图画的很好,特摘录过来:秋夜无霜

如上图:

调用方通过restTemplate封装的http连接池,这时候连接设置connectTimeout=3000,readTimeout=3000,然后网络请求http请求+端口调用到服务方,然后调用一个api(uri),这时候响应的时候,然后Spring框架对响应进行JSON序列化,然后写入Socket,这时候调用方(客户端)突然Socket端中断连接,而Server端正在进行输出流写,导致如上异常问题。

然后针对当前业务场景,看了今天300个请求,有不到10个出现这种问题,超时大多3、4秒样子,我们通知调用方增大连接池的超时时间,就不再出现这个问题。

 

最近气温变化大,冷暖转换明显,由于没有及时增添衣物,注意保暖,翎野君感染风寒,现在正在调养恢复中,希望大家也多多注意,春捂秋冻。

 

参考文章

https://blog.csdn.net/shichen2010/article/details/121769535

目录
相关文章
|
2月前
|
Java
如何在 Java 中处理“Broken Pipe”异常
在Java中处理“Broken Pipe”异常,通常发生在网络通信中,如Socket编程时。该异常表示写入操作的另一端已关闭连接。解决方法包括:检查网络连接、设置超时、使用try-catch捕获异常并进行重试或关闭资源。
126 5
|
2月前
|
数据采集 Java Linux
Java“Broken Pipe”解决
Java中遇到“Broken Pipe”错误通常是因为Socket连接被远程主机关闭,而本地程序仍在尝试写入数据。解决方法包括:1. 检查网络连接和防火墙设置;2. 增加超时设置;3. 使用异常处理捕获并重试。
464 4
|
4月前
|
IDE Java 分布式数据库
Apache HBase 落地JAVA 实战
Apache HBase 落地 Java 实战主要涉及使用 Java API 来操作 HBase 数据库,包括表的创建、删除、数据的插入、查询等操作。以下是一个基于 Java 的 HBase 实战指南,包括关键步骤和示例代码。
251 23
|
3月前
|
分布式计算 Java 大数据
大数据-147 Apache Kudu 常用 Java API 增删改查
大数据-147 Apache Kudu 常用 Java API 增删改查
44 1
|
3月前
|
Java Apache
Apache POI java对excel表格进行操作(读、写) 有代码!!!
文章提供了使用Apache POI库在Java中创建和读取Excel文件的详细代码示例,包括写入数据到Excel和从Excel读取数据的方法。
86 0
|
5月前
|
消息中间件 Java Kafka
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
127 1
|
5月前
|
Java 持续交付 项目管理
Maven是一款基于Apache许可的项目管理和构建自动化工具,在Java开发中极为流行。
Maven是一款基于Apache许可的项目管理和构建自动化工具,在Java开发中极为流行。它采用项目对象模型(POM)来描述项目,简化构建流程。Maven提供依赖管理、标准构建生命周期、插件扩展等功能,支持多模块项目及版本控制。在Java Web开发中,Maven能够自动生成项目结构、管理依赖、自动化构建流程并运行多种插件任务,如代码质量检查和单元测试。遵循Maven的最佳实践,结合持续集成工具,可以显著提升开发效率和项目质量。
66 1
|
5月前
|
Java 前端开发 Apache
Apache Wicket与Spring MVC等Java Web框架大PK,究竟谁才是你的最佳拍档?点击揭秘!
【8月更文挑战第31天】在Java Web开发领域,众多框架各具特色。Apache Wicket以组件化开发和易用性脱颖而出,提高了代码的可维护性和可读性。相比之下,Spring MVC拥有强大的生态系统,但学习曲线较陡;JSF与Java EE紧密集成,但在性能和灵活性上略逊一筹;Struts2虽成熟,但在RESTful API支持上不足。选择框架时还需考虑社区支持和文档完善程度。希望本文能帮助开发者找到最适合自己的框架。
57 0
|
7月前
|
消息中间件 存储 Java
深度探索:使用Apache Kafka构建高效Java消息队列处理系统
【6月更文挑战第30天】Apache Kafka是分布式消息系统,用于高吞吐量的发布订阅。在Java中,开发者使用Kafka的客户端库创建生产者和消费者。生产者发送序列化消息到主题,消费者通过订阅和跟踪偏移量消费消息。Kafka以持久化、容灾和顺序写入优化I/O。Java示例代码展示了如何创建并发送/接收消息。通过分区、消费者组和压缩等策略,Kafka在高并发场景下可被优化。
130 1
|
7月前
|
Java 应用服务中间件 Apache
安装和配置Apache Tomcat是部署Java Web应用程序的常见任务
安装和配置Apache Tomcat是部署Java Web应用程序的常见任务
188 7

热门文章

最新文章

推荐镜像

更多