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

WMS 一直 502,服务其实还活着

先看结论

直接访问 GeoServer 的 8080 端口一切正常,走 Nginx 就返回 502,刷新几次偶尔又成功。

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

现象

浏览器里所有 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”。

排查过程

  1. 在服务器上用 curl 直接请求 8080,确认上游本身是否正常。
  2. 对同一张图计时,判断是否超过 60 秒。
  3. 看 GeoServer 的 catalina.out 与 geoserver.log。
  4. 看 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)。