京东11.11大促主会场领京享红包更优惠

 找回密码
 立即注册

QQ登录

只需一步,快速开始

tomcat连pg数据库空闲超时问题解决

2025-3-13 10:48| 发布者: zhaojun917| 查看: 63| 评论: 0

摘要: 以下是解决 Tomcat 连接 PostgreSQL 数据库空闲超时问题的完整方案:​问题现象当 Tomcat 应用长时间无请求时,数据库连接因空闲超时被 PostgreSQL 关闭,导致后续请求报错:Connection closed unexpectedly或FATAL: ...
 以下是解决 Tomcat 连接 PostgreSQL 数据库空闲超时问题的完整方案:

问题现象

  • 当 Tomcat 应用长时间无请求时,数据库连接因空闲超时被 PostgreSQL 关闭,导致后续请求报错:
    Connection closed unexpectedly 或 FATAL: terminating connection due to idle-session timeout.
  • 解决方案

    1. ​调整 PostgreSQL 空闲超时配置

    • ​**修改 idle_in_transaction_session_timeout**​(事务内空闲超时)和 idle_session_timeout(会话空闲超时):
      sql
      复制
      -- 查看当前配置
      SHOW idle_in_transaction_session_timeout;
      SHOW idle_session_timeout;
      
      -- 设置为 10 分钟(示例值,根据业务调整)
      ALTER SYSTEM SET idle_in_transaction_session_timeout = '10min';
      ALTER SYSTEM SET idle_session_timeout = '10min';
      SELECT pg_reload_conf();  -- 重新加载配置

    2. ​配置 Tomcat 连接池(Tomcat JDBC Pool)​

    • ​**修改 context.xml**​(路径:Tomcat/conf/context.xml 或应用内的 META-INF/context.xml):
      xml
      复制
      <Resource 
          name="jdbc/postgres" 
          type="javax.sql.DataSource"
          driverClassName="org.postgresql.Driver"
          url="jdbc:postgresql://localhost:5432/mydb"
          username="user"
          password="pass"
          
          <!-- 连接池核心配置 -->
          maxTotal="20"                <!-- 最大连接数 -->
          maxIdle="10"                 <!-- 最大空闲连接数 -->
          minIdle="5"                  <!-- 最小空闲连接数 -->
          initialSize="5"              <!-- 初始连接数 -->
          
          <!-- 空闲连接回收策略 -->
          timeBetweenEvictionRunsMillis="30000"    <!-- 每30秒检查一次空闲连接 -->
          minEvictableIdleTimeMillis="540000"      <!-- 空闲9分钟则关闭(需小于数据库超时) -->
          
          <!-- 连接验证配置 -->
          validationQuery="SELECT 1"    <!-- 验证查询语句 -->
          testWhileIdle="true"         <!-- 空闲时验证连接 -->
          testOnBorrow="true"          <!-- 借用连接时验证 -->
          testOnReturn="false"         <!-- 归还连接时不验证 -->
      />

    3. ​启用 TCP Keepalive

    • 在 PostgreSQL 服务器端启用 Keepalive​(修改 postgresql.conf):
      ini
      复制
      tcp_keepalives_idle = 60      -- 60秒后发送Keepalive探测包
      tcp_keepalives_interval = 60  -- 探测包间隔60秒
      tcp_keepalives_count = 5      -- 最多发送5次探测
    • 重启 PostgreSQL 服务
      bash
      复制
      systemctl restart postgresql

    4. ​防止 Tomcat 连接泄漏

    • 确保代码中关闭连接
      使用 try-with-resources 或手动关闭 ConnectionStatementResultSet
      java
      复制
      try (Connection conn = dataSource.getConnection();
           Statement stmt = conn.createStatement();
           ResultSet rs = stmt.executeQuery("SELECT 1")) {
          // 操作数据
      } catch (SQLException e) {
          e.printStackTrace();
      }

    5. ​日志监控与调试

    • 启用 Tomcat 连接池日志
      logging.properties(路径:Tomcat/conf/logging.properties)中添加:
      properties
      复制
      org.apache.tomcat.jdbc.pool.level = FINE
    • 启用 PostgreSQL 连接日志
      postgresql.conf 中设置:
      ini
      复制
      log_connections = on
      log_disconnections = on
      log_statement = 'all'

    配置参数说明

    参数名说明
    minEvictableIdleTimeMillis空闲连接存活时间(需小于 PostgreSQL 的 idle_session_timeout
    validationQuery用于验证连接的 SQL 语句(简单查询如 SELECT 1
    testWhileIdle在空闲时验证连接是否有效
    testOnBorrow从连接池借用连接时验证有效性

    验证步骤

    1. 模拟空闲超时
      停止应用请求,等待超过 minEvictableIdleTimeMillis(如9分钟),观察日志是否自动关闭空闲连接。
    2. 触发错误场景
      手动终止 PostgreSQL 连接,验证连接池是否能自动恢复。

    常见问题排查

    • 错误日志中出现 Connection reset
      检查防火墙或网络设备是否主动关闭空闲连接,需调整其超时设置。
    • 连接池耗尽
      检查是否有连接泄漏(未关闭的连接),结合 log_connectionslog_disconnections 分析。

    通过以上配置,Tomcat 连接池会在数据库关闭空闲连接前主动回收或验证连接,避免超时错误。如果问题仍存,请提供具体日志和配置进一步分析! 🚀

关闭

站长推荐上一条 /6 下一条

QQ|手机版|小黑屋|梦想之都-俊月星空 ( 粤ICP备18056059号 )

GMT+8, 2025-4-4 06:21 , Processed in 0.025059 second(s), 17 queries .

Powered by Mxzdjyxk! X3.5

© 2001-2025 Discuz! Team.

返回顶部