更新内容:
Accept-Encoding
内容。直到今天我见过很多网站还是倾向使用独立的服务器部署自己的网站。但是在云服务更加完善的今天,已经有更好的选择。本文将介绍使用阿里云的 OSS+CDN 部署自己的前端页面,以及加速静态资源。
直接使用阿里云的 OSS+CDN 的方案有几大好处:
我已经将本文总结的实践放入了 terraform 工程,欢迎 terraform 的用户评测试用:https://github.com/abcfy2/oss_with_cdn_terraform
阿里云 CDN 需要绑定自己的域名,国内要求必须备案,所以务必先备案自己的域名。如果这个域名在阿里云购买的更好,几乎可以做到不用手改域名解析记录,阿里云会自动处理。
OSS 和 CDN 都是后付费的服务,因此需要保证账户有足够的余额。价格方案: https://cn.aliyun.com/price/product#/oss/detail
注意: 网站链接需要特别注意,阿里云 OSS 的网站托管是兼容 Angular 的路由的,也就是根目录只有一个
index.html
,其他目录的访问都应该 rewrite 到/index.html
。所以如果你的静态资源不是通过 Angular build 出来的,不应该使用/location/
这种路径页面跳转,应该使用/location/index.html
这种路径,否则访问/location/
将显示/index.html
中的内容。如果您的路径的确有/location/
这种路径,考虑开通 子目录首页具体的细则请参考阿里云的官方文档: 配置静态网站托管
这两个服务都是按量付费的,开通是不需要费用的。
每个独立的 bucket 可以当做一个独立的网盘对待,要求 bucket name 全局唯一,不能重名。创建一个前端托管的 bucket 参考配置如下:
bucket 创建之后,默认的 bucket 配置是不具有静态网站托管的功能的,因此需要做一些配置。参考配置如下:
OSS 目前的策略限制了不能通过 OSS 自己的域名直接打开index.html
,会变成下载。因此无论是否使用 CDN,都必须绑定自己的域名。由于启用 CDN 之后会加速 OSS,并且回源流量半价,还是挺划算的,因此建议启用 CDN。启用 CDN 的办法如下:
打开 CDN 控制台,点击添加域名:
稍等片刻之后,等待 CDN 配置之后,转到 CDN 控制台就可以看到这个域名了:
此时基本配置就已经结束了,之后你可以上传你的静态网站到这个 bucket 的根目录下了。不过在此之前可以做一些 CDN 的优化配置
CDN 支持定制 HTTP 响应头的功能,一个比较常见的设置是直接在 http 头中添加浏览器缓存的头(cache-control
),这个功能可以在缓存配置
这里直接配置缓存规则:
目前全站 https 已经是趋势了而且免费的证书服务目前也比较多了。阿里云 CDN 就支持申请 DigiCert 免费证书,并且自动续期。下面的HTTP/2
也建议启用:
上面的 DigiCert 免费证书申请需要特别注意,如果你的主机头是www
,必须将空主机头@
也CNAME
也解析到 CDN 上才能申请成功。
此外,性能优化个人建议全部勾选,可以减少部分带宽:
由于 CDN 开启了 gzip 和 br 压缩,为了提高命中率,可以考虑仅在 CDN 级别处理压缩资源,而 OSS 只响应未压缩的原始资源。同时由于 OSS 仅支持 gzip 压缩,因此如果不删除回源响应的 Accept-Encoding 头,将永远不会得到 br 资源,只可能得到来自于 OSS 的 gzip 资源。所以需要在 CDN 回源请求中删除 Accept-Encoding 头,只在 CDN 级别进行资源压缩,这样就可以响应给客户端 br 压缩的内容,减少 CDN 传输容量:
到此为止 OSS+CDN 的部分已经配置完毕了,只要把静态页面上传到 OSS 上就搞定了。建议通过 oss 客户端上传,可以支持批量拖拽上传,而不是在 OSS 控制台上一个一个上传。
这里我推荐阿里云官方的开源项目oss-browser,因为这个客户端可以跨平台,并且支持记录 AK,使用上很方便。
使用前需要开启账户的 AccessKey,或者专门创建一个低权限的子账户管理 OSS。
每次更新网站的时候,可能需要手工刷新下 CDN(尽管 OSS 配置中有个自动刷新 CDN 的功能,但我发现使用客户端是上传的时候无效。疑似通过 API 上传的文件不会触发 CDN 刷新)。进入 CDN 的控制台,点击刷新,输入一下要刷新的 URL 路径即可:
这里分享一下我个人的deploy_aliyun_oss.sh
脚本,拼接阿里云接口参数的函数部分改动自acem.sh这个项目,在此之上做了一些扩充,感谢贡献者。
脚本地址: https://github.com/abcfy2/deploy_cloud/blob/master/deploy_aliyun_oss.sh
使用说明参见 README: https://github.com/abcfy2/deploy_cloud/blob/master/README.md
AK 信息配置到环境变量中:
export OSS_ACCESS_KEY_ID=xxxxxxx
export OSS_ACCESS_KEY_SECRET=xxxxxxx
export OSS_BUCKET=your-bucket
# 如果没有启用阿里云的CDN,下面三个环境变量可以不赋值
export CDN_URL=https://www.domain.com/ # 阿里云的CDN刷新地址要求路径最后的/不能省略
export CDN_ACCESS_KEY_ID=xxxxxxx
export CDN_ACCESS_KEY_SECRET=xxxxxxx
export BASE_DIR=dist/
./deploy_aliyun_oss.sh
注意点:
OSS_ENDPOINT
覆盖,阿里云 oss endpoint 一览: https://help.aliyun.com/document_detail/31837.htmlCDN_URL
不存在,则不会在上传后自动刷新 CDN 路径URL
,上述配置只刷新了/
这一个访问地址。因此期望整个网站使用 CDN 友好(即每次更新资源之后,文件名或引用路径会改变,比如 Angular 或 Vue 的产品环境编译),如果期望整个网站被刷新,添加环境变量CDN_REFRESH_TYPE=Directory
覆盖觉得有帮助的话,不妨考虑购买付费文章来支持我们 🙂 :
付费文章