一次CDN缓存不同的问题 oral/oss/amazon/aliyun
2个关键的 curl
$ curl -I https://webapp.alo7.com/oral-assignment/
HTTP/2 200
server: Tengine
content-type: text/html
content-length: 3797
x-amz-id-2: 07VDcAu/UNbtXYFd0E1MLp3dm7EfesOu98ORDggytKySVJvpYXEFqhp1eZgrNpi8OWtqkJMTx+k=
x-amz-request-id: FEJ7SY68CRGDWTCY
date: Tue, 19 Aug 2025 03:19:17 GMT
cache-control: private, no-cache, no-store, must-revalidate
via: cache49.l2cn8116[69,68,304-0,H], cache14.l2cn8116[70,0], kunlun1.cn7174[80,80,200-0,H], kunlun9.cn7174[82,0]
last-modified: Fri, 08 Aug 2025 06:10:15 GMT
etag: "d75d15eb6bcab0dbf45442388d8b2770"
age: 0
ali-swift-global-savetime: 1755573556
x-cache: HIT TCP_REFRESH_HIT dirn:-2:-2
x-swift-savetime: Tue, 19 Aug 2025 03:19:16 GMT
x-swift-cachetime: 0
access-control-allow-origin: *
timing-allow-origin: *
eagleid: b4a3921d17555735568152359e
~/Downloads via 🐠 v20.19.2
$ curl -I https://webapp.alo7.com/oral-assignment/index.html
HTTP/2 200
server: Tengine
content-type: text/html
content-length: 3797
x-amz-id-2: MoQBHk6vrxFYy60Gn/hH7chogy7YkPfQGPKansSoBacUOqjRBbNmvBuQLRccD0aEZxpqFssAUSw=
x-amz-request-id: 56FWRGEQ3E423KYY
date: Tue, 19 Aug 2025 03:19:22 GMT
cache-control: private, no-cache, no-store, must-revalidate
last-modified: Tue, 19 Aug 2025 02:59:13 GMT
etag: "d75d15eb6bcab0dbf45442388d8b2770"
via: cache32.l2cn8116[73,73,200-0,M], cache35.l2cn8116[75,0], kunlun1.cn7174[84,85,200-0,M], kunlun3.cn7174[86,0]
ali-swift-global-savetime: 1755573561
x-cache: MISS TCP_MISS dirn:-2:-2
x-swift-savetime: Tue, 19 Aug 2025 03:19:21 GMT
x-swift-cachetime: 0
access-control-allow-origin: *
timing-allow-origin: *
eagleid: b4a3921717555735610351263e
你观察到两个 URL:
https://webapp.alo7.com/oral-assignment/
(目录式路径)https://webapp.alo7.com/oral-assignment/index.html
(具体文件路径)
虽然它们返回的内容类型和大小相同(content-length: 3797
,etag: "d75d15eb6bcab0dbf45442388d8b2770"
),但 Last-Modified
时间不同:
- 前者:
Fri, 08 Aug 2025 06:10:15 GMT
- 后者:
Tue, 19 Aug 2025 02:59:13 GMT
这看起来矛盾:同一个文件,为什么 Last-Modified
不同?
🔍 原因分析
尽管内容和 ETag 一致,表明最终返回的 HTML 内容是一样的,但 Last-Modified
头部不同,说明这两个请求在服务器或 CDN 处理流程中 被视为不同的资源或由不同机制生成。
以下是可能的根本原因:
✅ 1. 服务器端动态生成 index.html
的 Last-Modified
/oral-assignment/
是一个目录路径,服务器在收到请求时会自动查找默认首页(如index.html
),然后动态生成响应头。- 此时,
Last-Modified
可能取自服务器内部配置文件、路由时间、缓存生成时间,而非真实文件。 - 而直接访问
/oral-assignment/index.html
时,CDN 或后端识别为具体静态资源,使用该文件在对象存储中的真实上传/修改时间。
⚠️ 这意味着:两个请求虽然返回相同内容,但元数据(如
Last-Modified
)可能来自不同来源。
✅ 2. CDN/反向代理行为差异
从响应头看,使用了阿里云 Tengine + CDN(via: kunlun
, ali-swift-global-savetime
)。
对
/oral-assignment/
的请求:x-cache: HIT TCP_REFRESH_HIT
→ 从缓存命中last-modified: Fri, 08 Aug 2025
→ 可能是原始缓存条目的时间戳,未刷新元数据
对
/oral-assignment/index.html
的请求:x-cache: MISS TCP_MISS
→ 缓存未命中,回源拉取last-modified: Tue, 19 Aug 2025
→ 更接近真实文件时间(可能是新上传的)
👉 所以:/
路径命中的是旧缓存条目,其 Last-Modified
没有随内容同步更新,而直接访问 index.html
触发了回源,获取了更新后的元数据。
✅ 3. 静态资源部署时未同步更新所有路径的元数据
假设部署系统只上传了 index.html
文件,但没有清除所有相关缓存或更新目录索引的元信息:
/oral-assignment/index.html
的Last-Modified
正确反映最新上传时间(2025-08-19)- 但
/oral-assignment/
对应的“虚拟目录索引”仍保留旧的Last-Modified
(2025-08-08)
类似于:文件内容更新了,但目录列表的时间戳没更新。
✅ 4. ETag
相同说明内容一致,Last-Modified
不同仅说明元数据来源不同
ETag: "d75d15eb..."
完全相同 → 内容确实一致Last-Modified
是元数据,不是内容指纹- 因此:内容相同 ≠ 元数据相同
🧩 总结:为什么 Last-Modified
不同?
| 原因 | 说明 |
|------|------|
| 📁 路径处理机制不同 | 目录访问 /
是服务器自动映射到 index.html
,元数据可能不准确 |
| ☁️ CDN 缓存策略差异 | /
路径命中旧缓存,index.html
路径回源,获取新元数据 |
| ⏱️ 元数据未同步更新 | 部署新版本时,目录路径的 Last-Modified
未刷新 |
| ✅ 内容实际一致 | ETag
和 Content-Length
一致,说明文件内容无差别 |
✅ 建议解决方案
- 统一清除缓存:部署后清除
/oral-assignment/
和/oral-assignment/index.html
的 CDN 缓存。 - 使用版本化路径或查询参数:避免依赖
Last-Modified
做更新判断。 - 优先使用
ETag
进行缓存校验:比Last-Modified
更可靠。 - 检查服务器配置:确保目录索引返回的
Last-Modified
与实际文件一致。
📌 结论
❗
Last-Modified
不同,是因为两个 URL 在 CDN/服务器处理链中被视为不同资源路径,导致元数据来源不同;但ETag
一致,说明返回的内容是相同的。这不是文件不同,而是元数据同步或缓存机制不一致所致。
你可以放心,内容是一样的,但若依赖 Last-Modified
做缓存或更新判断,建议改用 ETag
。