04月08, 2017

是时候让博客全量CDN了

update 0409

找到死循环问题了, 不是CDN或Https问题, 是由于全站做了ls优化, 如果本地有缓存时回源的话会把无code版本缓存CDN中, 导致让有些用户既没有ls又没有code时进入刷新死循环... 先临时把ls关了.

为什么要用CDN

其实一个博客, 没啥流量, 是不是感觉没必要使用CDN, 但我想说的是: 折腾永无止境, 用户体验至上. 借用qa@龙哥的签名:

刷机越狱装系统, 办证刻章开证明.

一些解释

只是我的理解

  • CDN - 可以理解为人家IDC服务商在全国分布N多个节点, 可以把自己网站内容托管在她们节点上, 使全国范围访问速度加快
  • 内容回源 - CDN节点上本身没有你的网站内容, 在用户访问节点发现没有缓存时, CDN会从你源网站下载内容并缓存到她家, 以让下次访问直接从她家缓存输出, 这个过程叫回源
  • x-cache:HIT, MISS - HIT表示命中CDN缓存, MISS表示未命中

准备工作

添加canonical

由于是多CDN域名, 对博客所有页面添加canonical, 并指向主域, 防止被搜索引擎K

域名的确定

  1. 主CDN域: xuexb.com, 在阿里云生成SSL证书
  2. 静态资源域: static.cdn.xuexb.com, 托管在七牛云, 在七牛生成SSL证书
  3. 二级域: www.xuexb.com, 绑定阿里云ECS, 301跳转到xuexb.com
  4. 源站: source.xuexb.com, 绑定阿里云ECS, 100M独享带宽提供CDN回源
  5. 刷新CDN: reload.cdn.xuexb.com

所有的子域SSL证书都是由 Let's Encrypt Authority X3 签发

考虑缓存的更新方式

因为全站CDN后需要考虑下更新博客后如果处理CDN的缓存, 常见的有:

  1. 主动刷新 - 可以根据链接、目录主动请求CDN的API让其把缓存清空, 首次请求时会触发回源
  2. 主动预取 - 可以把更新的链接主动推送到CDN, 让其优先把该链接缓存下, 首次请求时会直接命中CDN缓存

结合博客本身的一些特点(分页、分类、标签等子页面比较多), 我使用方式1 - 主动刷新, 以网站根目录去刷新, 刷新成功后大概10秒钟全站生效, 在首次请求自动回源.

开发了个简单的页面https://reload.cdn.xuexb.com用来请求Aliyun-CDN-Api来刷新CDN缓存, 并在博客页脚添加了CDN图标: (削除) 已删除 (削除ここまで)

CDN缓存的逻辑请看图:

经和 @ddhhz 交流, 得出以下结论:

  1. CDN回源是每个节点都需要回源, 当节点被MISS一次后, 该节点下的再次请求会命中HIT
  2. 清除CDN缓存是全网生效的, 也就是会同步全部的节点

防灾策略

由于CDN流量是实时扣钱的, 万一哪个黑客大神要黑我(CC我), 那么我的余额扣完了CDN服务会直接关闭, 于是, 我把CDN主域xuexb.com的^/.well-known请求直接回源, 这样我就可以把主域使用Let's Encrypt Authority验证SSL证书, 当阿里云CDN出问题时(被黑), 我可以直接解析到ECS上访问, 证书都不用换的... 域名解析生效时间应该在10分钟左右.

开始配置

域名设置

  1. 在一个月黑风高的夜晚, 把主域xuexb.com转到阿里云CDN加速上
  2. 配置源站source.xuexb.com可以被访问
  3. www.xuexb.com301跳转到xuexb.com

缓存设置

  1. 针对^/admin不缓存, 添加: cache-control:no-cache, pragma:no-cache
  2. 针对其他资源配置(削除) expires:max (削除ここまで) 1d

nginx配置如:

server {
 server_name soruce.xuexb.com;
 #... 其他配置
 # 默认全缓存
 expires max;
 set $expires_time max;
 # 针对后台不缓存
 if ($request_uri ~* ^/admin(\/.*)?$) {
 set $expires_time -1;
 }
 # 如果文件不存在认识是后端, 代理到node
 if ( !-f $request_filename ){
 rewrite (.*) /proxy_node;
 }
 location = /proxy_node {
 expires $expires_time;
 if ($expires_time ~* -1) {
 add_header Cache-Control "no-cache";
 add_header Pragma no-cache;
 }
 # ... proxy_pass到node
 }
}

CDN生效后访问主域看response headers会多出来如下代码, 表示成功:

server:Tengine
via:cache13.l2et2-1[112,200-0,M], cache2.l2et2-1[113,0], kunlun3.cn288[0,200-0,H], kunlun1.cn288[8,0]
x-cache:HIT TCP_HIT dirn:1:531646989
x-powered-by:thinkjs-2.2.17
x-swift-cachetime:315360000
x-swift-savetime:Sat, 08 Apr 2017 09:02:37 GMT

而访问后台/admin时永远会是x-cache:MISS, 因为添加了no-cache.

监控服务

由于域名证书我用了3个地方, 分别是: 阿里云(1年)、七牛(1年)、Let's Encrypt Authority(3个月+自动续期), 所以使用一些服务来监控这些证书什么时候到期:

  1. 使用 https://letsmonitor.org 监控SSL证书到期时间, 提前7天警告
  2. 使用 https://uptimerobot.com/ 监控主域、源站服务是否可访问, 每4个小时轮询
  3. 阿里云、七牛云余额阀值报警

这里不得不感谢下 imququ大神~

速度对比

指标 升级前 升级CDN
对应IP 1个 42个
节点 1个 27个
测试总耗时 2.305s 2.695s
下载速度 261.048KB/s 1003.46KB/s

由于测速工具不稳定, 测试的时间上下浮动很大, 但节点要比升级前多很多, 毕竟CDN嘛~

todo

  1. 由于本身页面就有缓存, 即使刷新了CDN可能内容也得浏览器强刷才生效, 考虑nginx不缓存, CDN后台设置强制缓存, 这样应该好点, 待尝试
  2. 考虑把^/admin请求301回源站, 这样可以省点流量钱...
  3. 观察CDN对SEO的影响

本文链接:https://xuexb.com/post/cdn.html

-- EOF --

发表于 2017年04月08日 18:50:36 ,添加在分类 后端技术 下 ,并被添加「 前端优化 cdn 加速 」标签 ,最后修改于 2017年04月19日 01:45:53

提醒: 本文最后更新于 3186 天前,文中所描述的信息可能已发生改变,请谨慎使用。

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。

AltStyle によって変換されたページ (->オリジナル) /