首页 / 实战手册 / 服务端与发布
数据更新了,切片还是上周的样子
先看结论
数据库里新增的道路已经入库,WMS 直连能看到,瓦片服务却还是旧图,局部甚至出现新旧拼接的接缝。
现象
同一区域,GetMap 返回新数据,WMTS 瓦片仍是旧的。
放大到某个级别时,一半瓦片新、一半旧,边界处出现明显断裂。
响应头里能看到缓存命中:
HTTP/1.1 200 OK
Cache-Control: max-age=3600
Age: 2412
X-Cache: Hit from geowebcache
原因
| 层级 | 表现 | 处理位置 |
|---|---|---|
| GeoWebCache 磁盘缓存 | 所有客户端都旧 | GeoServer 缓存管理 |
| CDN 边缘缓存 | 不同地区新旧不一 | CDN 刷新 |
| 浏览器缓存 | 只有当前用户旧 | Cache-Control |
| 切片任务只更新了部分级别 | 低级别新、高级别旧 | 重新 seed |
切片按 图层 + 样式 + 网格集 + 级别 + 行列 作为键。
只改了数据、没改这些键,缓存就认为瓦片没变,不会重新生成。
排查过程
- 加一个随机查询参数请求同一瓦片,绕过缓存对比内容。
- 看响应头
Age与X-Cache,判断命中在哪一层。 - 检查该级别的切片任务是否真的跑过、覆盖范围是否完整。
curl -s -o /tmp/t1.png "https://gis.example.cn/geoserver/gwc/service/wmts?SERVICE=WMTS&REQUEST=GetTile&LAYER=workspace:roads&STYLE=&TILEMATRIXSET=EPSG:900913&TILEMATRIX=EPSG:900913:14&TILEROW=2418&TILECOL=10521&FORMAT=image/png"
curl -s -o /tmp/t2.png "https://gis.example.cn/geoserver/gwc/service/wmts?...&_=1700000000"
md5sum /tmp/t1.png /tmp/t2.png
解决方案
数据更新后主动截断对应图层的缓存,而不是等待过期。GeoServer 的
gwc 接口支持按图层清理:
curl -u admin:password -X POST \
"http://127.0.0.1:8080/geoserver/gwc/rest/seed/workspace:roads.xml" \
-H "Content-Type: text/xml" \
-d '<seedRequest>
<name>workspace:roads</name>
<gridSetId>EPSG:900913</gridSetId>
<zoomStart>0</zoomStart>
<zoomStop>18</zoomStop>
<type>truncate</type>
</seedRequest>'
发布流程里加一步版本号,把版本拼进 URL,从键上区分新旧,避免大范围重建:
# 前端瓦片地址带数据版本
https://gis.example.cn/tiles/roads/v20261029/{z}/{x}/{y}.png
# Nginx 长期缓存,因为 URL 变了就是新资源
location /tiles/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
频繁更新的图层不要做切片,直接走 WMS 动态渲染,或只对低频级别切片:
# geowebcache.xml 中为该图层关闭高倍缓存
<layer>
<name>workspace:live_traffic</name>
<enabled>true</enabled>
<expireCache>60</expireCache>
<expireClients>60</expireClients>
</layer>
验证
清理后同一瓦片两次请求内容一致,且与 GetMap 渲染结果吻合。
各缩放级别都能看到新数据,不再出现新旧拼接的接缝。
Age 从 0 开始增长,说明命中的是新生成的瓦片。
三层都要清:GeoWebCache 清了但 CDN 没刷新,用户看到的还是旧图。 数据发布后按“缓存服务器 → CDN → 浏览器强刷”的顺序逐层确认。
经纬志(2026)。《数据更新了,切片还是上周的样子》。https://www.jingweizhi.com/cookbook/tile-cache-inconsistent.html(访问日期 2026-11-03)。