简体   繁体   English

使用hikari连接池时“Socket read timed out”如何解决

[英]How to solve “Socket read timed out” when using hikari connection pool

I am developing an application using play framework (version 2.8.0), java(version 1.8) with an oracle database(version 12C).我正在使用带有 oracle 数据库(版本 12C)的播放框架(版本 2.8.0)、java(版本 1.8)开发应用程序。

There is only zero or one hit to the database in a day, I am getting below error.一天内数据库只有零次或一次命中,我遇到了错误。

java.sql.SQLRecoverableException: IO Error: Socket read timed out
    at oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:919)
    at oracle.jdbc.driver.PhysicalConnection.close(PhysicalConnection.java:2005)
    at com.zaxxer.hikari.pool.PoolBase.quietlyCloseConnection(PoolBase.java:138)
    at com.zaxxer.hikari.pool.HikariPool.lambda$closeConnection$1(HikariPool.java:447)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketTimeoutException: Socket read timed out
    at oracle.net.nt.TimeoutSocketChannel.read(TimeoutSocketChannel.java:174)
    at oracle.net.ns.NIOHeader.readHeaderBuffer(NIOHeader.java:82)
    at oracle.net.ns.NIOPacket.readFromSocketChannel(NIOPacket.java:139)
    at oracle.net.ns.NIOPacket.readFromSocketChannel(NIOPacket.java:101)
    at oracle.net.ns.NIONSDataChannel.readDataFromSocketChannel(NIONSDataChannel.java:80)
    at oracle.jdbc.driver.T4CMAREngineNIO.prepareForReading(T4CMAREngineNIO.java:98)
    at oracle.jdbc.driver.T4CMAREngineNIO.unmarshalUB1(T4CMAREngineNIO.java:534)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:485)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:252)
    at oracle.jdbc.driver.T4C7Ocommoncall.doOLOGOFF(T4C7Ocommoncall.java:62)
    at oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:908)
    ... 6 common frames omitted

db {
default {
driver=oracle.jdbc.OracleDriver
url="jdbc:oracle:thin:@XXX.XXX.XXX.XX:XXXX/XXXXXXX"
username="XXXXXXXXX"
password="XXXXXXXXX"
hikaricp {
  dataSource {
    cachePrepStmts = true
    prepStmtCacheSize = 250
    prepStmtCacheSqlLimit = 2048
      }
     }
  }
}

It seems it is causing due to inactive database connection, How can I solve this?似乎是由于数据库连接不活动引起的,我该如何解决? Please let me know if any other information is required?请让我知道是否需要任何其他信息?

You can enable TCP keepalive for JDBC - either be setting directive or by adding "ENABLE=BROKEN" into connection string.您可以为 JDBC 启用 TCP keepalive - 可以设置指令或在连接字符串中添加“ENABLE=BROKEN”。

  • Usually Cisco/Juniper cuts off TCP connection when it is inactive for more that on hour.通常,当 TCP 连接处于非活动状态超过一小时时,Cisco/Juniper 会切断连接。
  • While Linux kernel starts sending keepalive probes after two hours(tcp_keepalive_time).而 Linux kernel 在两小时后(tcp_keepalive_time)开始发送保活探测。 So if you decide to turn tcp keepalive on, you will also need root, to change this kernel tunable to lower value(10-15 minutes)因此,如果您决定打开 tcp keepalive,您还需要 root,将这个 kernel 可调到较低的值(10-15 分钟)
  • Moreover HikariCP should not keep open any connection for longer than 30 minutes - by default.此外,HikariCP 不应将任何连接保持打开超过 30 分钟 - 默认情况下。

So if your FW, Linux kernel and HikariCP all use default settings, then this error should not occur in your system.因此,如果您的 FW、Linux kernel 和 HikariCP 都使用默认设置,那么您的系统中不应出现此错误。

See HikariCP official documentation见 HikariCP官方文档

maxLifetime: This property controls the maximum lifetime of a connection in the pool. maxLifetime:此属性控制池中连接的最大生命周期。 An in-use connection will never be retired, only when it is closed will it then be removed.使用中的连接永远不会被淘汰,只有当它关闭时才会被删除。 On a connection-by-connection basis, minor negative attenuation is applied to avoid mass-extinction in the pool.在逐个连接的基础上,应用较小的负衰减以避免池中的大规模灭绝。 We strongly recommend setting this value, and it should be several seconds shorter than any database or infrastructure imposed connection time limit.我们强烈建议设置此值,它应该比任何数据库或基础设施强加的连接时间限制短几秒钟。 A value of 0 indicates no maximum lifetime (infinite lifetime), subject of course to the idleTimeout setting.值 0 表示没有最大生命周期(无限生命周期),当然取决于 idleTimeout 设置。 The minimum allowed value is 30000ms (30 seconds).允许的最小值为 30000 毫秒(30 秒)。 Default: 1800000 (30 minutes)默认值:1800000(30 分钟)

I have added the below configuration for hickaricp in configuration file and it is working fine.我在配置文件中添加了以下 hicaricp 配置,它工作正常。

## Database Connection Pool

play.db.pool = hikaricp
play.db.prototype.hikaricp.connectionTimeout=120000
play.db.prototype.hikaricp.idleTimeout=15000
play.db.prototype.hikaricp.leakDetectionThreshold=120000
play.db.prototype.hikaricp.validationTimeout=10000
play.db.prototype.hikaricp.maxLifetime=120000

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM