问题描述
使用CDN加速OSS以后发现返回的响应头里没有带Content-MD5头了,而直接通过OSS域名访问是会返回Content-MD5头的。刷新CDN缓存以后部分节点会返回Content-MD5,但是还是会有部分节点不返回Content-MD5。
< HTTP/1.1 200 OK
< Server: Tengine
< Content-Type: video/mp4
< Content-Length: 17369965
< Connection: keep-alive
< Date: Mon, 07 Jun 2021 11:33:58 GMT
< x-oss-request-id: 60BE042629F7AC37327E477F
< Vary: Origin
< x-oss-cdn-auth: success
< Accept-Ranges: bytes
< ETag: "D1EF74CEC4DE1F89F03A30C4647869F4"
< Last-Modified: Wed, 26 May 2021 04:10:19 GMT
< x-oss-object-type: Normal
< x-oss-hash-crc64ecma: 1958374103060741818
< x-oss-storage-class: Standard
< x-oss-version-id: null
< x-oss-server-time: 4
< Ali-Swift-Global-Savetime: 1623065639
< Via: cache25.l2cn3037[0,0,200-0,H], cache47.l2cn3037[1,0], cache47.l2cn3037[1,0], vcache39.cn2038[20,20,200-0,M], vcache33.cn2038[22,0]
< Age: 0
< X-Cache: MISS TCP_MISS dirn:-2:-2
< X-Swift-SaveTime: Mon, 07 Jun 2021 12:16:47 GMT
< X-Swift-CacheTime: 2592000
< Access-Control-Allow-Origin: *
< Timing-Allow-Origin: *
< EagleId: 73eec0b516230682076361320e
<
{ [2920 bytes data]
100 16.5M 100 16.5M 0 0 766k 0 0:00:22 0:00:22 --:--:-- 914k
* Connection #0 to host tutor-trans-video-online.fbcontent.cn left intact
排查过程
1. 排查CDN的日志
虽然X-Cache是MISS,没有命中缓存回源的,但是通过以下的Via信息可以看到是命中L2的缓存了,L2节点是l2cn3037。
Via: cache25.l2cn3037[0,0,200-0,H], cache47.l2cn3037[1,0], cache47.l2cn3037[1,0], vcache39.cn2038[20,20,200-0,M], vcache33.cn2038[22,0]
通过Ali-Swift-Global-Savetime: 1623065639可以知道该文件缓存到CDN节点的时间,unix时间戳1623065639转换成北京时间是2021-06-07 19:33:59。于是查对应时间段l2cn3037这个节点的日志信息,发现该L2上记录的状态码都是206,同时带了http_range字段,说明L2是Range回源OSS的,因此OSS响应了206。
2. 查OSS日志
查对应时间段OSS的实时日志,发现OSS日志字段记录的content_md5为"-",说明OSS确实没有响应content_md5字段。测试发现直接range请求OSS,OSS也是不会响应Content-MD5的,经确认OSS的策略的确如此。
3. 查CDN的range回源配置
确认CDN的range回源配置,发现配置的是on,也就是开启了range回源。
问题原因
整个过程是19:33:59有一个客户端发起了range请求,由于CDN域名配置了range回源,因此CDN会按照512KB的大小range回源OSS,OSS接到range请求以后响应状态码206并且不响应Content-MD5,这份响应被CDN缓存下来。后续客户端请求到对应的CDN节点,不管是否是range请求,由于CDN已经有缓存,就会直接返回之前缓存的不带Content-MD5的Response信息。
PS:为什么当时刷新缓存以后通过CDN去访问可以看到有Content-MD5?
答:因为当时刷新缓存以后,重新去访问的时候,客户端发起的不是range请求,而是普通的请求;与此同时,由于CDN上配置的range回源是"on",并不是"force",也就是不是强制range回源,因此CDN这种情况下回源的时候并没有发起range请求,OSS是会响应Content-MD5的。
解决方案
OSS会返回CRC,如果要做文件一致性校验的话可以通过x-oss-hash-crc64ecma字段获取CRC来做校验。
适用于
- CDN
- DCDN
- 对象存储OSS