WMS 一直 502,服务其实还活着
直接访问 GeoServer 的 8080 端口一切正常,走 Nginx 就返回 502,刷新几次偶尔又成功。
现象
浏览器里所有 WMS 请求返回纯文本错误页,GeoServer 自己的日志看起来没有异常:
502 Bad Gateway
nginx/1.24.0
Nginx 错误日志里能看到上游提前关闭连接:
2026/10/29 10:12:44 [error] 1842#1842: *31 upstream prematurely closed connection
while reading response header from upstream, client: 10.0.2.18,
request: "GET /geoserver/wms?SERVICE=WMS&REQUEST=GetMap&LAYERS=roads&WIDTH=2048&HEIGHT=2048 HTTP/1.1",
upstream: "http://127.0.0.1:8080/geoserver/wms?...", host: "gis.example.cn"
原因
| 原因 | 日志特征 |
|---|---|
| GeoServer 渲染超时,主动断连 | upstream prematurely closed connection |
| Nginx 默认 60 秒超时 | upstream timed out (110: Connection timed out) |
| 响应头超过缓冲上限 | upstream sent too big header |
| 上游地址或端口写错 | connect() failed (111: Connection refused) |
| GeoServer JVM 内存不足 | catalina.out 中出现 OutOfMemoryError: Java heap space |
大尺寸 GetMap(2048×2048 以上)需要数十秒渲染,Nginx 默认 60 秒读超时不够,
表现为“偶尔成功、多数 502”。
排查过程
- 在服务器上用
curl直接请求 8080,确认上游本身是否正常。 - 对同一张图计时,判断是否超过 60 秒。
- 看 GeoServer 的
catalina.out与geoserver.log。 - 看 Nginx 错误日志中的上游错误类型,区分超时、断连、拒绝。
curl -o /tmp/test.png -w "状态 %{http_code} 耗时 %{time_total}s\n" \
"http://127.0.0.1:8080/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&LAYERS=workspace:roads&SRS=EPSG:3857&BBOX=-8238310,4968198,-8237310,4969198&WIDTH=2048&HEIGHT=2048&FORMAT=image/png"
解决方案
按业务上限调整超时与缓冲。渲染耗时长的接口单独给一个 location, 避免全局放宽:
location /geoserver/wms {
proxy_pass http://127.0.0.1:8080/geoserver/wms;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 10s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
proxy_buffer_size 16k;
proxy_buffers 8 64k;
proxy_busy_buffers_size 128k;
}
限制单张图的像素总量,从根上避免超大请求。GeoServer 的
maxRequestMemory 与前端 WIDTH/HEIGHT 都应有上限:
# geoserver/wms/WMS 配置中
maxRequestMemory=65536 # 单位 KB,约 64 MB
maxRenderingTime=60
maxRenderingErrors=20
前端把大范围请求拆成多张 512 或 1024 的瓦片,配合浏览器并行下载, 单张渲染时间下降,502 会明显减少:
var layer = new ol.layer.Tile({
source: new ol.source.TileWMS({
url: '/geoserver/wms',
params: { LAYERS: 'workspace:roads', TILED: true },
tileGrid: ol.tilegrid.createXYZ({ maxZoom: 18, tileSize: 512 })
})
});
验证
连续请求 50 次大图,状态码全部 200,Nginx 错误日志不再出现
upstream prematurely closed connection。
单张图耗时 20 秒时也能正常返回。
前端缩放、平移过程中不再出现灰色块。
别只看 502:先确认是“连不上”还是“算得慢”。 连不上查地址与进程,算得慢查超时与渲染参数, 两种情况的改法完全不同。
经纬志(2026)。《WMS 一直 502,服务其实还活着》。https://www.jingweizhi.com/cookbook/wms-502-bad-gateway.html(访问日期 2026-11-03)。