簡體   English   中英

使用hikari連接池時“Socket read timed out”如何解決

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

我正在使用帶有 oracle 數據庫(版本 12C)的播放框架(版本 2.8.0)、java(版本 1.8)開發應用程序。

一天內數據庫只有零次或一次命中,我遇到了錯誤。

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
      }
     }
  }
}

似乎是由於數據庫連接不活動引起的,我該如何解決? 請讓我知道是否需要任何其他信息?

您可以為 JDBC 啟用 TCP keepalive - 可以設置指令或在連接字符串中添加“ENABLE=BROKEN”。

  • 通常,當 TCP 連接處於非活動狀態超過一小時時,Cisco/Juniper 會切斷連接。
  • 而 Linux kernel 在兩小時后(tcp_keepalive_time)開始發送保活探測。 因此,如果您決定打開 tcp keepalive,您還需要 root,將這個 kernel 可調到較低的值(10-15 分鍾)
  • 此外,HikariCP 不應將任何連接保持打開超過 30 分鍾 - 默認情況下。

因此,如果您的 FW、Linux kernel 和 HikariCP 都使用默認設置,那么您的系統中不應出現此錯誤。

見 HikariCP官方文檔

maxLifetime:此屬性控制池中連接的最大生命周期。 使用中的連接永遠不會被淘汰,只有當它關閉時才會被刪除。 在逐個連接的基礎上,應用較小的負衰減以避免池中的大規模滅絕。 我們強烈建議設置此值,它應該比任何數據庫或基礎設施強加的連接時間限制短幾秒鍾。 值 0 表示沒有最大生命周期(無限生命周期),當然取決於 idleTimeout 設置。 允許的最小值為 30000 毫秒(30 秒)。 默認值:1800000(30 分鍾)

我在配置文件中添加了以下 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