正篇

最近发布了徒步反穿武功山,以及自驾皖浙赣的游记文章,点我直达 ,我分享到了 v2ex 以及 linux.do ,各路网友都说图床太慢了。由于原文图片数量的确较多,我的图床部署在家里,然后只有 VPS 的6Mbps小水管,在并发不大的时候阅读文章还行(图片加载的速度还OK,并且有配置懒加载,所以体验还行),但是昨天发了帖子之后有几波流量激增。于是我寻找办法:

  • 准备使用活菩萨 cloudflare,但是要整体迁移域名解析到 cf,因为我这个域名有经过备案,并且数量众多,而且还要兼顾国内访问速率,我就放弃了 cloudflare 方案
  • 准备在源图床那边创建新的存储策略,当前是存储在本地磁盘的,然后想想又要买对象存储,又放弃
  • 最后发现了腾讯云的 edgeone,开通试试一个月只要4.8元,实付款4.7,最近微信支付很多借记卡、信用卡减免活动

最终我买了一个月的 edgeone,只花费4.7元~

现在部署好了 cdn,访问速度大大增加。当前时间点 2025-08-19 10:30:42 edgeone 流量情况
edgeone流量情况.webp

我这篇文章不算是教程吧,只能是个人的心路历程,我也不想写保姆级教程,太费事了。在此就简单讲讲过程和原理。

  1. 首先购买了一个月的 edgeone 产品,需要绑定站点,首先绑定根域名,也就是 940304.xyz 然后经过认证
  2. 域名认证方式是:添加 TXT 类型记录,主机记录和对应的值都是 edgeone 给出的,我的域名托管在 dnspod,需要在 dnspod 那边改
  3. 也可以不认证根域名,每个二级域名都分别认证
  4. 通过CNAME 方式接入 CDN,需要先停止解析或删除之前的 image 主机名的 A记录(DNS A记录),然后添加 image 主机名的 CNAME 记录(因为同一个主机名A记录和 CNAME记录只能有一个条)
  5. 创建成功后就等待 edgeone 下发 cdn 配置,等待部署生效即可

我顺利的部署成功,也看到 edgeone 流量页面产生了非常多的数据,当前我博客中的多图文章访问体验肯定就好很多了。

但是后面我发现一个问题,就是图片资源访问后返回头当中的 Cache-Control 始终是 max-age=3600,这说明 cdn 边缘节点只会缓存这张图片一个小时,如果用户在一个小时之后访问同链接会无法击中缓存,导致cdn节点回源获取原始文件,这势必会增加很多源站的流量,我的公网VPS以及家里服务器的流量都会增大,设置CDN的效果就大为下降了,而且我这就是图床程序,资源是静态的,不需要长时间变动。一般情况下图片资源都会设置30天后过期,也就是 max-age=2592000(单位s),于是我开启了排查。

在部署 edgeone 之前,我的图床架构是这样的
图床旧的网络架构.webp

在部署 edgeone 之后,我的图床架构变成这样
部署了cdn后的图床架构.webp

在任意有网络机器执行 curl -I https://image.940304.xyz/i/2025/05/21/682dd7d3137c3.jpg 发现返回 Cache-Control: max-age=3600,我开启了漫长的排查,总结下来就是

1、在VPS上修改 nginx 配置,显式增加 Cache-Control 的返回头,设置成 public, max-age=2592000,但是无果
2、在以上基础上,区分单独的匹配图片的 location,因为之前是一个反向代理 location / 就能搞定

配置是这样的

location ~* \.(jpg|jpeg|png|gif|webp|ico|css|js|svg|woff2)$ {
                proxy_pass http://127.0.0.1:81;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Forwarded-Proto https;
                proxy_set_header Host $host;

                # 30天缓存(仅对静态资源)
                add_header Cache-Control "public, max-age=2592000, s-maxage=2592000";

                # 跨域允许设置,允许所有跨域
                add_header 'Access-Control-Allow-Origin' *;
                # 自定义 Debug 头部(仅用于测试)
                add_header HDKRESP "This-request-matched-jpg-location_test"; # 新增
                # 跨域允许设置结束
                # 防盗链设置,因为上述跨域是允许所有的,这里就要设置防盗链从而进行域名的白名单设置
                valid_referers none blocked 940304.xyz *.940304.xyz hellodk.cn *.hellodk.cn hellodk.com *.hellodk.com 10.10.10.5;

                #nginx不允许嵌套if语句,这个很关键,否则nginx -t 会测试失败,无法reload或者start nginx服务

                set $block_access 0;

                # 如果 referer 无效
                if ($invalid_referer) {
                        set $block_access 1;
                }

                # 根据之前的判断结果决定是否拦截
                if ($block_access) {
                        rewrite ^/ https://i.imgur.com/CB4Fseq.jpeg;
                }
        }

这样的确能增加Cache-Control 的返回头,但是edgeone 那边始终没有生效。我还去lsky pro 图床程序的源 apache2 服务端添加了 Cache-Control 头,因为根据 edgeone 的规则,会先读源站的缓存相关的返回头(Cache-Control:s-maxage, Cache-Control:max-age, Expires),如果有会优先遵循源站的配置

edgeone 的文档:https://cloud.tencent.com/document/product/1552/87651

edgeone默认缓存规则
edgeone默认缓存规则.webp

默认缓存规则文字说明
默认缓存规则文字说明.webp

3、发现修改vps nginx配置无果,我进入了 lsky pro 容器,做了以下操作

# Apache 需要启用 mod_headers 才能使用 Header set 指令,启用这个模块
a2enmod headers

# 修改生效配置文件 `/etc/apache2/sites-enabled/000-default.conf` 可以通过命令 `apache2ctl -S` 寻找生效的虚拟主机所在文件
# 并增加如下配置
<LocationMatch "^/i/.*\.(jpg|jpeg|png|gif|webp|ico|bmp)$">
    Header set Cache-Control "public, max-age=2592000"
</LocationMatch>

# 重启apache2服务
service apache2 restart

现在图床源站点会给静态图片资源返回 Cache-Control 了,在图床容器中执行 curl -I http://localhost/i/2025/05/21/682dd7d3137c3.jpg 有如下返回

HTTP/1.1 200 OK
Date: Tue, 19 Aug 2025 03:11:18 GMT
Server: Apache/2.4.53 (Debian)
Last-Modified: Wed, 21 May 2025 13:40:35 GMT
ETag: "ef67-635a58279843c"
Accept-Ranges: bytes
Content-Length: 61287
Cache-Control: public, max-age=2592000
Content-Type: image/jpeg

在 edgeone 管理页面清除了这个URL https://image.940304.xyz/i/2025/05/21/682dd7d3137c3.jpg 的缓存,从 EO-Cache-Status MISS 到 HIT(也就是第一次请求未击中缓存cdn节点回源了,到第二次击中了缓存),返回的 max-age 仍然是 3600

4、开始排查 edgeone 这边,终于找到了原因所在!

需要在这里点击站点加速,我以为默认的全局配置就是对的,因为设置的是遵循源站的 Cache-Control,所以一直没细看
点击站点加速.webp

这里全局配置是正确的,没毛病,但是右侧还有一个规则引擎默认是打开的(但是默认没有任何配置,尼玛坑死我),并且优先级更高。
全局配置和规则引擎.webp

规则引擎默认打开并且默认无配置坑我导致max-age一直是3600!!!(欲哭无泪
规则引擎默认打开并且默认无配置坑我导致max-age一直是3600.webp

最后我因为不需要个性的规则引擎配置,我就将这边关掉了,直接使用全局配置,遵循源站的 Cache-Control 即可。

最终执行 curl -I https://image.940304.xyz/i/2025/05/21/682dd7d3137c3.jpg 返回了 Cache-Control: public, max-age=2592000 最终解决,这样可以减少 cdn 回源的频率,需求满足!

ok,如果你有任何疑问,欢迎留言与我讨论。

番外篇

edgeone国际版测速分享到X或者Facebook得FreePlan,网站 https://edgeone.ai 甚至分享到X+分享到Facebook可得两份FreePlan
edgeone国际版测速分享到X或者Facebook得FreePlan.webp

我等当前买的国内版失效之前的几天就切换到国际版。但是需要注意的是,腾讯云的一份身份认证只能实名制一个腾讯云账号,edgeone国际版要想使用中国大陆节点需要实名认证的账号才行。我的身份已经实名了国内版的了,后面大概就选择国际节点

国内版edgeone产品,4.7元买的一个月
国内版edgeone产品4.7元买的一个月.webp