You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

通过JBoss运行应用时PostgreSQL出现最大连接数错误求助

解决JBoss连接PostgreSQL时的最大连接数错误

咱们先把这个报错的核心点掰明白:FATAL: remaining connection slots are reserved for non-replication superuser connections,这句话直白点说就是——数据库给普通用户留的连接槽已经全占满了,剩下的仅有的几个连接是专门给超级用户(比如默认的postgres账号)预留的,这也是为啥你用PGAdmin能正常连,因为PGAdmin大概率用的是超级用户账号,而JBoss应用用的是普通业务账号,没资格用预留槽。

下面咱们一步步排查解决:

1. 先确认数据库的连接现状

先用超级用户登录PostgreSQL,执行这几个SQL看看真实情况:

-- 查看数据库允许的最大连接数
SHOW max_connections;
-- 查看留给超级用户的预留连接数
SHOW superuser_reserved_connections;
-- 统计当前各用户的连接数
SELECT usename, count(*) FROM pg_stat_activity GROUP BY usename;

执行后你会发现:你的业务用户(JBoss用的那个)的连接数,已经接近max_connections - superuser_reserved_connections的数值,把普通连接槽彻底占满了。

2. 排查JBoss连接池的配置问题

这是最常见的诱因,要么是连接池开太大,要么是连接没被及时回收:

  • 找到JBoss里你的数据源配置文件(一般是standalone.xmldomain.xml里的<datasource>节点)
  • 重点检查这几个参数:
    • max-pool-size:连接池最大连接数,绝对不能超过数据库给普通用户留的连接数(也就是max_connections - superuser_reserved_connections),建议比这个值小个5-10,留些余量
    • idle-timeout-minutes:空闲连接超时时间,设置个10-15分钟,让闲置的连接能被自动回收
    • validation-query:加个简单的验证SQL(比如SELECT 1),让连接池能检测失效连接并及时清理

给你贴个参考配置:

<datasource jndi-name="java:jboss/datasources/YourAppDS" pool-name="YourAppDS" enabled="true">
    <connection-url>jdbc:postgresql://your-db-host:5432/your-db-name</connection-url>
    <driver>postgresql</driver>
    <pool>
        <max-pool-size>25</max-pool-size>
        <min-pool-size>5</min-pool-size>
        <idle-timeout-minutes>10</idle-timeout-minutes>
    </pool>
    <security>
        <user-name>your-app-user</user-name>
        <password>your-app-pwd</password>
    </security>
    <validation>
        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"/>
        <validation-query>SELECT 1</validation-query>
        <validate-on-match>true</validate-on-match>
    </validation>
</datasource>

3. 检查应用代码的连接泄漏问题

如果连接池配置没问题,那大概率是代码里没正确关闭连接:

  • 比如JDBC操作后,没在finally块里关闭ConnectionStatementResultSet
  • 用ORM框架(比如Hibernate)时,没正确关闭会话(Session),导致连接一直被占用

你可以登录JBoss的管理控制台(默认地址http://localhost:9990),查看连接池的实时状态,如果In Use Connections数值只增不减,那肯定是有连接泄漏,得去排查代码里的资源释放逻辑。

4. 临时应急方案(不建议长期用)

如果要紧急恢复服务,可以临时调大PostgreSQL的连接数,但要注意:每个连接会占用几MB内存,调太大会把数据库内存撑爆。

  • 修改postgresql.conf文件:
    max_connections = 120  # 比如原来设的是80,适当调大
    superuser_reserved_connections = 5  # 保持默认或微调
    
  • 重启PostgreSQL服务生效

但这只是权宜之计,核心问题还是要靠优化连接池和修复代码泄漏来解决,不然过段时间还是会爆。

内容的提问来源于stack exchange,提问作者Lina

火山引擎 最新活动