close connection error java.sql.SQLRecoverableException: IO Error: Broken pipe

 java.sql.SQLRecoverableException: IO Error: Broken pipe

1 错误信息

ERROR [com.alibaba.druid.util.JdbcUtils] - close connection error
java.sql.SQLRecoverableException: IO Error: Broken pipe

2 分析

遇到这个问题,一般是程序访问服务(比如数据库)时遇到的。这之间存在着好几个网络 通信节点:

程序 –> 连接池 –> 网卡 –> 防火墙 –> 路由器 –> 防火墙 —> 服务端网卡 —> 服务端静态路由 –> 服务端防火墙 –> 服务监听 –> 服务

除了程序与连接池(一般集成在一起),其他任何一个节点中断连接,都有可能引发这个问 题,尤其是防火墙。而一般将某个连接中断原因,是因为这个连接空闲了太长的时间(保持 连接却不做任何事情)。网络防火墙、tcp网络、服务器本地防火墙、监听这几个节点上都 有空闲连接控制。

下面分别通过配置连接池、服务器上的tcp网络、数据库层面、来解决空闲连接被异常中 断的问题。

2.1 连接池

现在国内大都使用druid 作为程序的连接池。那么该连接池针对空闲连接提供了检测和 校验机制。比如在申请使用该连接时,先测试该连接是否可用,定时检查空闲连接是否 可用等,空闲连接定时执行无意义的SQL以保证会话被验证为alive,推荐配置如下:

spring.datasource.druid.test-while-idle=true
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.validation-query-timeout=1000
sping.datasource.druid.min-Evictable-Idle-Time-Millis=300000
sping.datasource.druid.time-Between-Eviction-Runs-Millis=3000
spring.datasource.druid.keep-alive=true
spring.datasource.druid.remove-abandoned=true
spring.datasource.druid.remove-abandoned-timeout=3600
spring.datasource.druid.log-abandoned=true

一般使用以上配置后,就不会再出现连接中断的问题。

2.2 TCP网络

  • keepalive 类Unix系统上,TCP 连接的 keepalive 可以在应用层实现,也可以在 TCP 中提供。 这个问题存在争议,因此 TCP 连接的保活探测并不是 TCP 规范中的一部分。但为了方便 ,几乎所有类 Unix 系统均在 TCP 中提供了相应的功能。

    常见类UNIX系统中的tcp keepalive:

    操作系统保活定时器
    AIX# no -a | grep keep
     tcp_keepcnt = 8
     tcp_keepidle = 14400
     tcp_keepintvl = 150
    Linux# sysctl -A | grep keep
     net.ipv4.tcp_keepalive_intvl = 75
     net.ipv4.tcp_keepalive_probes = 9
     net.ipv4.tcp_keepalive_time = 7200
    FreeBSD#sysctl -A | grep net.inet.tcp
     net.inet.tcp.keepidle=…
     net.inet.tcp.keepintvl=…

    不同系统上的各参数的时间单位不尽相同。在 AIX 上, tcp_keeidle/tcp_keepinit/tcp_keepintvl 的时间单位是 0.5 秒;而在 Linux 上, net.ipv4.tcp_keepalive_intvl 和 net.ipv4.tcp_keepalive_time 的时间单位则为秒。并 且,上述参数仅对运行在其上的服务器应用连接有效。

    note
    在 Solaris 上可通过“ndd /dev/tcp \?”命令显示上述类似参数信息,而在 HP

    Unix 上则可通过 nettune 或 ndd 命令进行查询。

    由于所有类 Unix 系统上均支持这种功能,因此,在接下来的部分中我们将基于 AIX 系统 具体讲述上述参数的意义和作用机制。

    控制参数参数说明
    tcp_keepcnt关闭一个非活跃连接之前进行探测的最大次数,默认为 8 次
    tcp_keepidle对一个连接进行有效性探测之前运行的最大空闲时长,默认值为 14400(即 2 个小时)
    tcp_keepintvl两个探测的时间间隔,默认值为 150 即 75 秒

    我们要通过设置这些参数,使其控制时间间隔要小于防火墙设置的最大空闲时间,如果不了 解防火墙的设置,可以将该tcp_keepintvl的值设置为3分钟以内,一般网络防火墙对于 空闲会话的限制不会短于这个时间。

  • tcp retries 这里有另外一个现象,当连接被异常中断,但是程序这端的服务器没有收到相关终止信息 时,由原来存在的会话继续发送报文时,不会得到反馈,超过一定时间后,TCP会重新发 送该报文,直到超过最大允许重发次数。所以,有些时间,程序收到broken pipe 信息 时,是在一段时间以后(常见的是15分钟)。而在测试、开发人员的眼中,就是业务从开 始执行到报错, 中间等待了很久,比如15分钟。这里涉及到Linux内核对tcp 重发报文 次数的控制: net.ipv4.tcp_retries2 ,可以通过文件/proc/sys/net/ipv4/tcp_retries2 进行临时调整。

    其规则是:配置重传次数小于9的话,就是指数增长时间,如果大于9的话,就是最大超时时间.

    TCP_RTO_MIN=(HZ/5)=0.2s

    TCP_RTO_MAX=(120HZ)=120s

    linear_backoff_thresh = ilog2(1205)=ilog2(0x258)=9

    timeout:未超过linear_backoff_thresh=9的部分按TCP_RTO_MIN 2的指数倍增长,超过 的部分按TCP_RTO_MAX线性增长

    比如:

    sysctl_tcp_retries2=9,则timeout=1023TCP_RTO_MIN=204.6s sysctl_tcp_retries2=11时,timeout=1023TCP_RTO_MIN+2TCP_RTO_MAX=448.6s

针对这个问题,我们可以将重传次数设置得小一些。比如设置为3.

2.3 数据库监听

数据库也会把一些长时间没有任何操作的会话给kill掉,并不会给出任何的反馈。当程序 使用长连接,再次请求这些会话时,就会遇到报错。从数据库角度来讲,可以把空闲时间 设置得更长一些,但是这样是存在风险的,日积月累后,数据库中可能存在大量的空闲连 接,由于数据库一般会限制最大连接数的。如果大量的空闲连接存在,可能导致新的连接 无法建立。

  • ORACLE oracle中对空闲会话的检测是在$ORACLE_HOME/network/admin/sqlnet.ora中配置

的,参数是sqlnet.expire_time ,单位是秒。比如:

sqlnet.expire_time=180
  • MySQL 设置wait_timeout 指定空闲时间,单位是秒,最长不建议超过1天。

Author: halberd.lee

Created: 2019-09-26 Thu 21:20

Validate

转载于:https://www.cnblogs.com/halberd-lee/p/11594548.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误是Java数据库连接时发生的错误,通常是由于网络问题或数据库服务器故障引起的。具体的错误信息是“java.sql.sqlrecoverableexception: io 错误: undefined error”。 可能的解决方法包括检查网络连接是否正常、检查数据库服务器是否正常运行、检查数据库连接参数是否正确等。如果问题仍然存在,可以尝试重新启动数据库服务器或联系数据库管理员寻求帮助。 ### 回答2: java.sql.sqlrecoverableexception: io错误: undefined error,意味着Java程序在试图与数据库建立连接或进行数据库操作时出现了无法恢复的错误,导致连接断开或操作失败。 这个错误可能由多种原因引起,其中一些常见的因素包括: 1. 数据库服务器宕机或故障。如果数据库服务器出现故障或停机,Java程序无法访问数据库,就会出现这个错误。检查一下数据库服务器是否正常运行,并尝试重新连接数据库。 2. 网络连接故障。如果网络连接存在问题,可能会导致Java程序无法与数据库进行通信,从而导致io错误。请检查网络连接是否正常,例如,尝试使用ping命令测试数据库服务器是否可达。 3. 数据库连接池配置错误。如果连接池配置不正确,可能会导致连接超时或泄漏,从而导致无法恢复的错误。检查一下连接池配置是否正确,并尝试改变参数值以解决问题。 4. 应用程序代码错误。如果应用程序代码存在问题,例如使用了错误的SQL语句或参数,可能会导致无法恢复的错误。检查一下应用程序代码是否正确,并尝试修复或重写代码。 无论是哪种原因导致了这个错误,都需要仔细检查并修复问题,以确保Java程序能够与数据库顺利通信。如果无法自行解决问题,可以寻求专业技术人员的帮助。 ### 回答3: java.sql.sqlrecoverableexception: io 错误: undefined errorJava 中一个常见的异常错误,这个错误通常是由于数据库连接超时或者数据库服务器无响应而导致的。 在 Java 中,程序通过 JDBC 来实现与数据库的连接和数据交互。当程序尝试连接数据库时,它会发出一个请求并等待数据库服务器响应。如果该请求长时间未得到响应或者网络连接断开,就会出现 io 错误: undefined error 异常。 通常,在出现这种异常时,我们需要检查以下几个方面: 1. 数据库服务器是否正常运行:我们需要检查数据库服务器是否已经启动并正在运行,并且可以通过正确的端口访问。如果无法访问,则可能是因为服务器故障或网络问题。 2. 数据库连接超时设置:有时候,数据库连接需要一定的时间才能建立,而程序可能在这之前就已经超时了。为了解决这个问题,我们可以增加 JDBC 连接的超时设置。 3. 数据库访问权限:如果数据库连接成功了,但是程序无法进行数据访问,那么可能是因为程序没有足够的访问权限。我们需要检查数据库用户的权限是否正确。 4. 确认 JDBC 驱动版本是否正确:有时候不同版本的 JDBC 驱动程序之间会出现一些不兼容的问题,这也可能导致 io 错误: undefined error 异常。 总之,当出现 java.sql.sqlrecoverableexception: io 错误: undefined error 异常时,我们需要全面检查相关问题,确定究其原因,以便尽快解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值