效果

惯例不多比比,直接上效果:

首页图片加载

加速前,注意看图片的加载速度(最后一张图约 4MB),此时全靠服务器小水管传输
加速后,图片加载明显快了很多(首页大图因为随机轮换还没缓存所以慢很多)

Ping

https://tool.chinaz.com/speedtest

IP 裸连,因为加速前忘了测了,应该差不多
CDN 加速后

PageSpeed Insights

https://pagespeed.web.dev/

加速前
加速后,呃……怎么还更慢了

为什么需要 CDN

这个系列的前三篇文章都是节流,不花钱的。但是开源节流,开源在前面,节流在后面,如果源就那么点,又能节流到哪里去呢?

开源,那就是要花钱的。很直接的想法是,服务器访问慢要加钱,那为什么不直接升级服务器配置,而是购置 CDN 呢?

一个很重要的因素是,同样的带宽和流量,CDN 的性价比远高于云服务器那点小水管。云服务器所在的数据中心,那可是非常尊贵的地段,网络质量非常好,可靠性是小数点后面一大堆 9,而且带宽一般也是服务器独享,再加上商业宽带和骨干网昂贵的价格,云服务器的小水管比金子还贵也就不稀奇了。

相反,CDN 本身就是压低成本的思想催生出来的,节点都是往便宜了挑,而且本身也是分布式的,对网络质量和稳定性要求自然相对不高(挂了还有其他节点顶上),成本就降下来了。

CDN 的分布式还带来一个延迟优势:你云服务器网络再牛逼再金贵,也不能突破光速的限制,在美国和中国直接隔着太平洋有 10 毫秒延迟吧。但是 CDN 节点肯定美国也有,那用户直接访问这个节点,延迟肯定低啊。至于 CDN 节点从源服务器拉缓存要多久,一般用户也不太关心:关我屁事。

如果全站 CDN,CDN 还能保护你的 IP。本来域名解析直接指向 IP,随便一个在线工具都能查出来,想干点什么坏事容易得很。你一套个 CDN,坏家伙解析域名只能指向 CDN 节点的 IP,你的 IP 就相对安全了。当然,国内域名要备案,除非你备案信息作假,不然直接查就知道你的 IP 了,以及可以狂刷你 CDN 让你欠费也是一种攻击,不过这些都是扯远了。(个人博客大不了就断网大法呗)

CDN vs DCDN

其实我这里选 DCDN 的主要原因很简单,阿里云目前有三个月 50 元额度 DCDN 的白嫖活动,而 CDN 没有……

DCDN 是什么

CDN 是在节点中缓存静态资源,这样用户访问时就不用去挤源服务器的小水管,而是就近取 CDN 的资源。而 DCDN 除此之外还能加速动态资源。用阿里云的文档说,就是DCDN的智能选路系统,可以自动规划最优网络路线访问源站获取数据,并响应给客户端, 达到加速的目的。同时,DCDN 节点间、DCDN 节点和源站间均会保持一定数量的长连接,进一步减少动态请求的请求耗时,达到加速的目的。像是在线游戏、金融交易等场景,套个 DCDN 就和套个加速器一样。当然,某种意义来说,个人博客不太需要加速动态请求,所以普通 CDN 也够了。

为什么阿里云

原因很简单,除了有白嫖活动之外,我的云服务器也是阿里云的,用同一个厂的解决方案是非常自然的事情。

此外,大厂的 CDN 费用真不一定比其他的贵。综合下来(主要是图省事)就先用着阿里云了。

为什么不 CDN + OSS

CDN + OSS 应该是网上非常常见的 WordPress 加速方案。在 WordPress 上用 OSS 存储静态资源,也是一种提高访问速度的方案,还能一定程度上存算分离,方便分别扩展算力和存储,做负载均衡和分布式也很方便;而 CDN 加速 OSS 更是发挥了这种优势。

但是要做到 CDN + OSS ,首先要做到动静分离,将静态资源迁移到 OSS 上。对于大站点来说这是必须的,但是像我这种个人小站就有点懒了,直接鼠标一拖上传到 WordPress 的媒体库更方便。当然,现在有插件可以简化镜像到 OSS 的过程,所以这只是次要问题。

主要问题是,好像我加个 OSS 没啥必要……我现在云服务器硬盘 40G,每月流量 1000G(虽然是 2M 小水管),不出意外做博客肯定绰绰有余。但是 OSS 价格(没有说明均为按量计费):

上传到 OSS (流入)免费,同一个区域流出到云服务器也是免费(不同大区和非阿里云机器算是外网收费的)。回源流出到 CDN 节点 0.15 元/GB(非阿里云主机算外网收费),而 CDN 是 0.24 元/GB。

那么,相比 CDN 直接加速全站的 云服务器费用 + CDN 费用,如果上个 OSS 还要给多一份 OSS 的存储费和流量费。这样做访客体验快不快我不知道,但是我的钱包一定瘪得很快。

配置 DCDN

添加域名

  1. 填原本服务器的域名。当然也可以填一个新的域名,看个人需求。
  2. 这里一般国内建站都是选内地就好了,海外流量包贵很多,如果你主要面向海外那还是用 Cloudflare 的免费 CDN 吧。当然,因为我目前是白嫖,所以选个全球看看效果。
  3. 点击添加源站信息:
  4. 类型一般选择 IP,除非你没套 CDN 前是 CNAME 解析。
  5. 填原本服务器的 IP。
  6. 如果网站是 HTTPS 就选 443,否则选 80。(这年头 HTTPS 应该是标配了吧)

第一次添加需要做个 TXT 解析验证域名所有权。我已经做过了,所以没法放图,根据阿里云指导来就好了。

添加完了直接返回域名列表。

域名解析 CDN 节点

警告

如果你的域名也作为宝塔面板的域名访问,一定要换成 IP 访问或者另外绑个域名,不然这个域名解析到 CDN 节点后宝塔面板将无法通过域名访问。

点击复制 CNAME 记录

去把域名做个 CNAME 解析到阿里云给出的CDN节点上。

没有过程,都套CDN了总不会连域名解析都不会操作吧

配置

回到 DCDN 控制台,刷新一下网页。如绿框所示就是解析成功。然后做点配置。

静态协议跟随源一般选择“跟随客户端协议”。回源 HOST 和回源 SNI 个人博客单域名可以不开,开的话一般填自己的加速域名。

动态加速如果关闭就变成普通的 CDN 了。如果开的话,付费时除了CDN流量包之外,还要额外购买动态请求资源包或者按量付费

若要开启 HTTPS,把以前域名解析源服务器 IP 的证书拿过来用就行了。如果开启 HTTPS 的话,付费时除了CDN流量包之外,还要额外购买静态 HTTPS 请求资源包或者按量付费

全开,没什么好说的。

DCDN 计费

定价:https://www.aliyun.com/price/product?spm=a2c4g.212986.0.0.1fad5889ev9UeH#/dcdn/detail

阿里云 DCDN 是这样计费的:

  1. (必买)CDN 下行流量:这个是 CDN 和 DCDN 共享的。
  2. (非必买)静态 HTTPS 请求:也是 CDN 和 DCDN 共享的。静态 HTTP 似乎是免费的,而开启 HTTPS 要收费。
  3. (非必买)动态请求:DCDN 独有的计费项。
  4. (非必买)IP 和 websocket 加速:也是 DCDN 独有,个人博客站点不需要买这个,像游戏、语音通话的服务才要买。

比如,如果我想要功能全开的 DCDN,最乞丐的套餐包是:

  • 100G 1年 中国内地的CDN下行流量:14 元(50G 有点不太够)
  • 1000万次 1年 静态 HTTPS 请求次数:40 元
  • 100万次 1年 动态请求数:14 元

加在一起就是一年 68 块钱。

如果关掉动态请求加速,把 DCDN 当成普通 CDN 使用,那就可以不买动态请求套餐包,总价就是 54 元一年;纯 HTTP 访问同理,也可以不买静态 HTTPS 请求套餐包。

如果最乞丐的 1000 万次 / 100 万次 一年的套餐包还是嫌贵,但是又想要静态 HTTPS 请求和动态请求,也可以不买套餐直接用多少给多少钱。下面是按量收费定价:

按量计费的话,静态 HTTPS 一年 40 可以用 800 万请求,动态一年 14 约 93 万次。

问题:静态资源没有正确缓存

问题排查

在阿里云后台发现回源流量非常多,并且动态请求数量远大于静态请求。

动态请求数占据总请求数的绝大部分

这不正常,因为一般个人博客流量大头就是图片,而图片应该是被缓存的,也就是说不应该产生那么多回源流量。

然后找了个图多的文章( 赛博朋克2077 截图系列(3):杂 – Eterance的小窝),在 14:50 左右连着开了好几次(用 InPrivate 防止浏览器缓存),然后查看阿里云控制台里的分析:

可以看到动态请求流量和动态请求数几乎占了全部,回源流量非常多。极有可能是图片没有 CDN 缓存。

在后台查看宝塔,可见页面刷新时服务器一直在上传。

上传了十几秒,此时图片在缓慢加载,显然图片没有缓存

阿里云后台查看缓存命中率,发现非常高,说明并不是图片缓存命中率低(图片有缓存但是没有命中),而应该是压根没有缓存,被当作动态请求回源服务器了。

最后,下载离线日志检查(离线日志大概要 4-6 小时之后才可供下载):

在阿里云控制台这里下载,解压后记事本打开

实锤了这一猜想,日志里的几乎所有图片都被当成动态请求回源服务器了。下面是截取的一个片段:

[5/Jul/2023:14:51:56 +0800] 211.97.3.171 - 1275 "https://blog.baldcoder.top/articles/%e8%b5%9b%e5%8d%9a%e6%9c%8b%e5%85%8b2077-%e6%88%aa%e5%9b%be%e7%b3%bb%e5%88%973%ef%bc%9a%e6%9d%82/" "GET https://blog.baldcoder.top/wp-content/uploads/2023/06/photomode_10012021_135956-%E5%B7%B2%E7%BC%A9%E5%B0%8F90.webp" 200 5302 502707 -,DYNAMIC|CHARGE|NOTLAST "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.157" "image/webp"

这个 webp 图片请求有 DYNAMIC 字样,应该是被当成动态请求了。

手动指定静态缓存规则

动静态加速规则

开启了“动态加速”才需要设置这里。

首先在动静态加速规则里,静态文件类型全部勾上。

然后添加静态路径,把 WordPress 的媒体库 URL 添加进去,也就是只要是媒体库里的文件都当做静态资源缓存。如果你和我一样没有修改,那么路径是 /wp-content/uploads/*

缓存配置

接下来修改缓存过期时间。

注意权重和过期时间,过期时间按照个人实际情况设置,图片等很少修改的可以适当延长,容易修改的代码文件缩短间隔,设置为 0 就等于不缓存

下面是我的规则内容(大小写敏感):

  • /wp-content/uploads/
  • gif,png,bmp,jpeg,jpg,webp,cur,aniGIF,PNG,BMP,JPEG,JPG,WEBP,CUR,ANI
  • html,htm,shtml,HTML,HTM,SHTML
  • css,js,CSS,JS
  • php,jsp,asp,PHP,JSP,ASP
  • mp3,wma,flv,mp4,wmv,ogg,avi,MP3,WMA,FLV,MP4,WMV,OGG,AVI
  • doc,docx,xls,xlsx,ppt,pptx,txt,pdf,DOC,DOCX,XLS,XLSX,PPT,PPTX,TXT,PDF

采取措施后

流量几乎都是静态 HTTPS ,回源流量极小,正常了。

加载网页时,宝塔后台显示没有长时间高带宽上行了。

截取离线日志:

[5/Jul/2023:16:47:03 +0800] 211.97.3.171 - 5 "https://blog.baldcoder.top/articles/%e8%b5%9b%e5%8d%9a%e6%9c%8b%e5%85%8b2077-%e6%88%aa%e5%9b%be%e7%b3%bb%e5%88%973%ef%bc%9a%e6%9d%82/" "GET https://blog.baldcoder.top/wp-content/uploads/2023/06/photomode_10012021_135956-%E5%B7%B2%E7%BC%A9%E5%B0%8F90.webp" 200 811 502938 HIT "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.157" "image/webp"

没有 DYNAMIC 而是 HIT,那就是命中缓存了。


封面图:https://www.pixiv.net/artworks/66348345