经纬志
首页 / 实战手册 / 服务端与发布

连接池耗尽,WMS 集体 503

先看结论

早上九点业务高峰,所有图层一起变慢,随后整站返回 503,重启 GeoServer 才能恢复。

最后验证 2026-11-03 · 多技术栈 · PostgreSQL 16 · 更新 2026-10-29 · 引用本文

现象

GeoServer 日志连续出现等待连接超时,之后所有请求失败:

ERROR [geoserver.wms] -
org.geoserver.platform.ServiceException: Rendering process failed.
Caused by: org.apache.commons.dbcp2.ConnectionPoolTimeoutException:
  Timeout waiting for connection from pool
    at org.apache.commons.dbcp2.Datasource.waitForConnection(Datasource.java:1305)

HTTP/1.1 503 Service Unavailable
Retry-After: 120

数据库侧 pg_stat_activity 显示连接数顶到 max_connections。

原因

原因判断依据
连接池上限太小池配置 maxActive=8,并发请求 30
连接未归还异常路径下没有 close(),空闲连接数持续为 0
慢查询长期占用pg_stat_activity 中 state=active 且 query_start 很早
数据库 max_connections 不足报 too many clients already
每个图层一个数据存储连接池数量随图层数线性增长

排查过程

先在数据库侧看连接来源与状态,再回到 GeoServer 看池配置:

SELECT usename, state, count(*)
FROM pg_stat_activity
GROUP BY usename, state
ORDER BY count(*) DESC;

SELECT pid, now() - query_start AS duration, query
FROM pg_stat_activity
WHERE state = 'active' AND now() - query_start > interval '30 seconds';

GeoServer 侧打开连接池的详细日志,确认是否持续等待:

# 数据存储配置中
maxActive=20
maxIdle=10
minIdle=2
maxWait=-1        # 改为 10000(毫秒),快速失败而不是无限等待
testOnBorrow=true
validationQuery=SELECT 1

解决方案

按并发量调整池上限,并设置合理的等待时间。注意所有工作区的池总和 不能超过数据库的 max_connections:

# postgresql.conf
max_connections = 200
shared_buffers = 4GB

# 三个数据存储,每个池 20,合计 60,留出余量给管理连接
# GeoServer 数据存储 -> 连接池参数
maxActive=20
maxIdle=10
minIdle=4
maxWait=10000

排查泄漏:在代码里确保 Connection 在 finally 中关闭, 不要把它放进长生命周期的对象里:

Connection conn = null;
try {
  conn = dataSource.getConnection();
  PreparedStatement ps = conn.prepareStatement(sql);
  ResultSet rs = ps.executeQuery();
  // 处理结果
} finally {
  if (conn != null) conn.close();
}

慢查询加索引,避免一次请求占用连接几十秒:

CREATE INDEX CONCURRENTLY idx_roads_geom
  ON roads USING gist (geom);
ANALYZE roads;

验证

压测 50 并发持续 5 分钟,pg_stat_activity 的连接数稳定在 60 以内, 不再出现 Timeout waiting for connection from pool。 WMS 响应时间回到 300 ms 以内,503 消失。

先分清是“不够用”还是“不归还”:空闲连接数为 0 且持续等待, 多半是泄漏;连接数高但大多处于 idle,才是池上限设置过小。

引用本文

经纬志(2026)。《连接池耗尽,WMS 集体 503》。https://www.jingweizhi.com/cookbook/geoserver-db-pool-exhausted.html(访问日期 2026-11-03)。