通过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.xml或domain.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块里关闭Connection、Statement、ResultSet - 用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




