【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

作者:烨烁

CDN 加速 OSS 是常见的站点动静分离的方式,可以实现将静态资源存储在 OSS 上,并通过 CDN 加速 OSS 实现静态资源的访问加速效果。但是在实际使用的过程中可能会出现使用方法以及配置上的问题导致使用上出现难题。本文档主要就 CDN 加速 OSS 的配置以及各注意事项进行描述已解决本使用场景中遇到的问题。

  1. 使用场景描述

图 1 所示即是常见的站点动静分离的解决方案。从该图中可以查看到整个站点数据包括动态资源和静态资源两个部分,其中动态资源主要是指站点的 web 程序以及数据库等内容,其主要部署在云服务器 ECS 上(数据库可部署在 RDS 上)。该部分控制了整个站点的业务逻辑,用户会发动态请求到业务服务器,业务服务器决定了系统逻辑返回给客户以什么动态数据。而另外一部分则是以静态脚本(例如 css 、 js 文件等)、图片、音视频等静态资源。这些静态资源存储在 OSS 中,然后通过 CDN 对这些静态资源的下载操作进行加速。而维护 OSS 中的数据则可以通过 ECS 内网操作 OSS 以进行增删改操作。
【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

图 1. 动静分离架构示意图

这样设计的优势在于:

  1. 静态资源的访问将直接通过 CDN 的逻辑直接返回给客户端,而不需要占用 ECS 的各项负载(主要包括带宽、 CPU 以及内存等)。同时静态资源的上传也可以通过客户端直接上传至 OSS ,避免再经过ECS 。
  2. CDN 和 OSS 本身提供的下行带宽非常的高( OSS 限制 5Gbps ,而 CDN 不限制)。因此 ECS 仅需要保证动态数据所占用的带宽资源即可(一般动态资源占用的下行带宽相比于静态资源较少),可以节省ECS 的带宽规格,节约成本。
  3. 同一数据中心的 ECS 和 OSS 之间是可以直接通过阿里云的内网进行数据交互的,因此可以保证 ECS 和
    OSS 的网络质量。
  4. CDN 提供了靠近客户端的节点缓存静态资源,因此在访问静态资源时会优先在 CDN 节点中获取以减少网络传输距离。保证了静态资源的服务质量。同时 CDN 本身提供全球节点加速,可以一定程度的缓解运营商的国际链路对访问带来的影响。
  5. 常见问题及解决方案

CDN 加速 OSS 的配置方法可以参考通过 CDN 加速 OSS Bucket,但是经常有用户配置完成后发现使用异常的情况,大致可以分为以下三类。接下来我们详细描述:

解析未生效。

问题1:域名解析异常。
在 CDN 加速 OSS 的场景中当 CDN 和 OSS 都配置完成后将分别得到 CNAME 域名, CDN 本身有加速域名对应的 CNAME 域名,而OSS 有本身的域名。这里生效时需要用户设置该域名的 CNAME 解析到 CDN 的 CNAME 域名上方可生效。例如图 2 中即是 CDN 加速域名及其对应的 CNAME 域名,用户在配置完成 DNS 解析后可以通过图 3 的方式验证测试。
【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

图 2. CDN 的 CNAME 域名示意图

【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

图 3. dig命令检测解析是否生效示意图

问题 2 :域名选择错误。
使用 CDN 加速 OSS 的场景是肯定需要用户提供一个域名解析到 CDN 上方可提供服务。而这里常有客户选择自己域名的主域名或者www子域名等已经使用的域名添加到 CDN 和 OSS 上。
由于域名本身限制一个主机记录仅能够配置一个 A 记录或者 CNAME 记录,因此如果该域名已经解析到您的服务器上的话请不要将该域名再添加在 CDN 和 OSS 上。特别需要注意的是如图 4 中的“自动添加CNAME 记录”的操作将会直接在云解析中添加 CNAME 记录,因此如果该域名有其他的用途可能会导致访问异常。
【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

图 4. 自动添加解析记录示意图

访问异常。

问题 1 :回源 host 未绑定在 OSS 的域名管理
CDN 的回源设置包括:回源地址(可以设置为 IP 或者域名)、回源端口和回源 Host 几个参数。由于 OSS 是没有提供固定 IP ,而是通过 OSS 域名提供服务的,因此 CDN 回源 OSS 时回源地址写 OSS 的公网域名即可(注意:CDN 回源都是通过公网回源的,因此这里只能够填写 OSS 的公网域名,不可以使用 OSS 的内网地址)。而回源端口则可以选择 80 或者 443 分别代表了 http 协议回源和 https 协议回源的两种方式。而回源 Host 参数表示了 CDN 请求回到源站时HTTP 的 Request 头中的 Host 字段的值。
该 Host 字段指代了源站服务器上具体是哪个应用 server 提供服务的,在 OSS 的场景中由于同一区域的 OSS 是由提供一组前端机提供服务,因此前端机是需要根据 Host 字段识别具体访问的是哪个bucket 中的数据。
在 CDN 加速 OSS 的场景中的回源 Host 设置方法一般有两种:设置回源 Host 为 OSS 本身的域名和设置为加速域名。如果设置为 OSS 本身的域名当然 OSS 前端机是可以识别为访问的哪个 Bucket ;而如果设置加速域名那么是需要将该域名绑定在该 Bucket 的自定义域名中,如图 5 中所示的 wqvod.pier39.cn 这个加速域名回源 Host 为加速域名时时需要在Bucket中绑定该域名不能才可以正常访问的。
【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

图 5. 回源Host示意图

问题 2 :OSS 默认首页不生效
OSS 可以配置静态托管功能,可以配置默认首页和 404 页面。默认首页即使通过 Bucket 的根目录即可直接访问设置的默认首页 html 。例如如下图的配置,当访问 “http://dongchics.oss-cn-hangzhou.aliyuncs.com/” 时就会显示 “http://dongchics.oss-cn-hangzhou.aliyuncs.com/1.html” 的内容提供服务。
【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

图 6. 默认首页设置示意图

但是当添加 CDN 加速 OSS 后并且在 CDN 上配置“私有 Bucket 回源”功能后会发现通过 CDN 加速域名的根目录访问无法获取得到 OSS的默认首页,而访问得到的是如下图所示的一个 XML 文件。从该文件的内容上可以查看到返回的内容是 OSS 调用 listObjects 返回的结果,其原因就是当开启“私有 Bucket 回源”后, CDN 访问 OSS 的URL 就会是签名 URL ,而带有签名参数的 URL 访问 OSS 的根目录是不会执行默认首页跳转逻辑的,而是直接调用了 listObjects 并显示返回如图7中的结果,因此该问题的处理方案即使关闭“私有 Bucket 回源”即可。
【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

图 7. 默认首页未生效示意图

问题 3 :CDN 导致 OSS 文件大小变化
OSS 通过 putObject 等上传方式都是会在 response 头中记录content-length 和 content-MD5 的信息返回给客户端,如图8所示。用户可以根据该信息确定本地下载得到的文件是否与 OSS 服务器端存储的数据是否一致。
【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

图 8. Response头信息示意图

但是当客户使用 CDN 加速 OSS 后验证本地的数据有时会发现本地下载的文件与 OSS 上存储的文件的 content-length 或者 content-MD5不一致。出现该情况有以下原因:

  • 获取 CDN 上的历史缓存。由于 OSS 上的文件更新而 CDN 上仍然缓存着历史的旧数据导致的该问题,可以通过刷新 CDN 缓存解决。
  • CDN 的智能压缩功能。 CDN 会对满足特定条件的文件自动做 gzip压缩,当客户端发送的 Request 头有 Accept-Encoding : gzip ,即表示客户端支持 gzip 压缩并且满足CDN智能压缩就会进行压缩,而压缩后就会导致该文件更改为 chunked 编码,将无法获取得到 content-length 。
  • CDN 的页面优化功能。 CDN 针对于 html 文件提供了 trim 的功能,即 CDN 在开启页面优化功能后可以帮助用户自动去掉 html 页面中的空格以及注释,这样可以减少下行流量。但是这就会导致客户端接收到的 content-length 或者 content-MD5 发生变化。
  • HTTP 劫持问题。当如果客户端到 CDN 的 L1 节点或者 CDN 的 L2 节点回源到源站使用 HTTP 协议时数据传输是非加密的,因此是有可能出现在网络传输的过程中包内容被篡改的情况。这种情况就会导致客户端接收与 OSS 存储内容不一致。该问题可以通过修改为 HTTPS 协议规避该问题。

问题 4 :CDN 回源到老版本图片处理域名
OSS 默认提供的是“oss-cn-.aliyuncs.com”的域名提供服务,但是针对于老版本的图片处理仍然提供了“img-cn-.aliyuncs.com”供老版本的图片处理样式方式访问(通过@!样式名或者@样式处理串)。但是相比于 OSS 本身的域名,图片处理域名是不提供 HTTPS 协议的,因此在 CDN 上回源到 OSS 图片处理域名是不可以设置回源到 443 端口的,同时是不可以开启协议跟随回源功能的,否则将会导致 HTTPS 协议访问出现异常的情况。

问题 5 :CDN 加速后 OSS 的 CORS 配置未生效
当出现来自不同的域的 JavaScript 动态请求其他域的静态资源时会触发浏览器的跨域请求,而这时浏览器会在 HTTP 的 Request 头中添加Origin 头表示是由哪个域访问该资源的。而 OSS 作为静态资源存储产品是允许设置 CORS 头设置允许哪些域进行跨域访问的。详细的设置请参考OSS 的 CORS 设置
OSS 当接收到客户端的 Request 头中带有 Origin 头并且与 CORS 配置匹配的话那么会在 Response 头中 Access-Control-Allow-Origin等头信息表示允许跨域访问。但如果 Request 头没有 CORS 头的话那么 OSS 是不会返回 Access-Control-Allow-Origin 等头信息。这种情况在使用 CDN 加速 OSS 的时候就会导致如果历史有没有跨域请求OSS 的返回信息缓存在 CDN 节点上,下次访问触发跨域时直接获取缓存数据导致鉴权不通过的。
该问题最好的解决方案就是在 CDN 上配置 CORS 头,这样保证不管客户端是否有触发跨域请求都会在 Response 带有 Access-Control-Allow-Origin 等头信息的。避免由于历史的未触发 CORS 的缓存数据影响真正的跨域请求,具体的设置请参考CDN配置CORS头

问题 6 :过滤参数导致回源请求缺失
OSS 的权限包括公共读写、公共读和私有三种权限,对公共读的Bucket 执行写操作核对私有的 Bucket 执行读和写的操作时都是需要访问的时候加上身份验证的签名参数的。这里以读为例,以 URL 的方式读取 OSS 的资源时是需要加上 OSSAccessKeyId 、 Expires 和Signature 三个参数的 queryString 的参数才可以正常访问的,如果没有添加这些参数就会报“403 Access Denied”的错误。
而 CDN 上是提供了过滤参数的功能是指当 CDN 收到请求 URL 后去除掉 URL 中的 querystring 查看是否有缓存文件命中,如果没有的话就会使用没有 querystring 的 URL 回源拉取资源。例如:由于 CDN加速 OSS 的访问URL是“http://wqtest.test.com/1.jpg? Expires=1511700494&OSSAccessKeyId=TMP.AQGmSnv_MDL_qdYESUo2KTjtyS5aqHdRVF8Cjko_zeyEC4rwnnOWyTVfoBAHMC4CFQDa1RE0F6h3Z1s0RV3OyZfdL1jmFgIVAM2ENr7Ae5c1LqDyi3LO2ba4seyk&Signature=NS8xhKGyyHEzzIK4CmqaxzCcfwo%3D”,其中 wqtest.test.com 是开启了过滤参数的 CDN 加速域名。那么CDN 节点在受到该请求后会将该 URL 改写成“http://wqtest.test.com/1.jpg”,然后依次查看 CDN 的 L1 节点和L2 节点上是否有缓存数据,如果有的话就直接将该缓存数据反馈给客户端,否则就会回源到 OSS 。而这时 OSS 如果是私有的话接收到该请求将无法正常访问就会抛出 403 Access Denied 的错误。
这里最直接的处理办法就是关闭过滤参数功能,这样回源的时候就会带上完整的 querystring 。但是这样设置同样会带来一个问题就是当queryString 中的参数发生更改后那么 CDN 会认为是完全不同的 URL重新缓存,因此这种情况下可能会导致 CDN 缓存命中率下降。其他的解决方案建议参考后面的“问题 7 :私有 Bucket 回源和鉴权功能的设置”。

问题 7 :私有 Bucket 回源和鉴权功能的设置
在问题 6 中我们介绍了当 OSS 设置为私有时不可以开启过滤参数并且当签名 querystring 发生变化时还会影响 CDN 缓存命中率。该问题的解决方案就是 CDN 开启私有 Bucket 回源。
该功能将使 CDN 的请求回源 OSS 的时候自动带上签名 querystring参数,而不需要客户自己在请求 CDN 的时候设置。这样即实现了 OSS 本身资源的安全防护而又不影响 CDN 的缓存命中率。
同时如果客户需要对 CDN 的请求也要求鉴权的话可以在 CDN 上配置鉴权功能,同时鉴权参数发生更改是不影响缓存命中率的。

刷新问题。

CDN 加速 OSS 的场景提供了 OSS 源文件更新后提供自动刷新 CDN缓存的功能,该功能是在 OSS 控制台的域名管理页面中开启,如图 9所示。开启该功能是需要该域名同时在 CDN 和 OSS 上绑定才可以正常使用,否则就很按照图 8 中的第一条记录无法开启该功能。
【 CDN 最佳实践】CDN 加速 OSS 常见问题及处理思路

图 9. CDN 缓存自动刷新示意图

上一篇:Centos+Apache实现多站点及强制https访问


下一篇:GRANT/SELECT View时的遭遇ORA-01720和ORA-01031错误