跳转至

CDN 加速网站

承载此博客的服务器是在线下的一台 Linux 服务器,通过 frp 到腾讯云放出来的,近期在主页加了 dify 机器人之后发现有点卡,然后想到使用 CDN 服务加速,因为备案是在腾讯云,为了方便使用 腾讯云 CDN 服务,后续可以换成其他的。

mkdocs.linuxnbg.com

二、加速域名配置

1. 添加加速域名和源站配置

路径:CDN控制台 → 域名管理 → 添加域名。

添加域名和回源设置
image-20250402155444247

2. 缓存与性能优化

1. 缓存规则配置

推荐策略

文件类型 缓存时间 规则示例 适用场景
图片/静态资源 30天 .jpg;.png;.css;.js 商品页、官网
HTML文件 5分钟 .html;.htm 资讯类动态页面
API接口 不缓存 /api/* 实时数据查询

忽略参数:开启后?version=1?version=2视为同一资源,避免重复缓存。

1. 配置缓存规则配置 2. 提升访问性能,有效减少传输内容大小,节省开销。
image-20250407211941804 image-20250407212043005

3. 防止费用超额

image-20250407212755422 image-20250407212634838

4. 配置 https 与 CHAME

证书申请

  • 在 “HTTPS配置” 中选择 “申请免费证书”(支持单域名,有效期3月);

  • 强制跳转:开启 “HTTP→HTTPS” 以避免混合内容警告;

  • HTTP/2.0:启用以提升多路复用效率,降低延迟。

HTTPS 加速与证书配置 使用ping http://cdn.example.com验证解析是否生效。
image-20250407212843097 image-20250407213046726

看看之前的效果与 cdn 之后的效果

image-20250407222215237
image-20250407222118909 image-20250407220149962

安全防护与访问控制(防止盗刷与攻击)

1. 防盗链配置

类型选择

Referer黑白名单:限制特定域名访问(如仅允许*.http://example.com);

时间戳鉴权(TypeC模式):需在URL中加入签名与时间戳,示例:

http://cdn.example.com/{sign}/{timestamp}/image.jpg

2. IP访问限频与黑名单

限频设置:建议静态资源限频10-30次/秒,动态API限频5-10次/秒;

黑名单:屏蔽恶意IP段(如1.2.3.0/24),支持导入TXT格式列表。

高级功能与运维管理

1. 资源预热与刷新

预热操作

◦ 路径:控制台 → 刷新预热 → 提交URL/目录(如`http://cdn.example.com/images/);

URL不支持带通配符预热,提交任务时必须包含 http:// 或 https://且至少含有1个路径(域名后至少含有1个"/"),例如 http://www.test.com/test.html,一行一个

◦ 建议每日凌晨预热高频资源,减少白天访问延迟。

缓存刷新:更新文件后立即提交刷新请求,支持批量操作(最多1000条/次)。

2. 全球加速与边缘计算

边缘脚本:通过EdgeOne编写JS脚本,实现AB测试、请求头修改等逻辑;

QUIC协议:开启QUIC(基于UDP)以优化高丢包网络下的传输效率。

3. 日志分析与监控

日志下载:支持按小时/天下载访问日志,分析用户行为与热点资源;

实时监控:查看流量、带宽峰值、命中率等指标,设置阈值告警(如带宽超80%触发通知)。

CDN 的 URL 刷新、目录刷新和 URL 预热的顺序需要依据不同的业务场景来确定,以下为你详细分析常见场景及对应的操作顺序:

场景一:网站新内容上线

当你有全新的网站内容(如文章、视频、新页面等)要上线,并且希望这些内容能快速被用户流畅访问,操作顺序如下:

  1. URL 预热:新内容在源站部署完成后,马上进行 URL 预热。这是因为新内容在 CDN 节点上原本没有缓存,通过 URL 预热,CDN 会主动从源站获取新内容并缓存到各个节点。例如,电商网站推出新的促销活动页面,在页面部署到源站后,立即提交该页面的 URL 进行预热,这样当大量用户访问该活动页面时,就能直接从离他们最近的 CDN 节点获取内容,减少响应时间。
  2. 无需刷新操作:由于是新内容,CDN 节点上不存在旧的缓存,所以无需进行 URL 刷新或目录刷新操作。

场景二:网站内容更新

如果网站上已有内容发生了更新,比如修改了图片、更新了文章内容或者调整了页面样式等,操作顺序如下:

  1. 刷新操作
  2. 单个文件更新:若只是单个文件(如一张图片、一个 CSS 文件)的内容有更新,执行 URL 刷新。这会让 CDN 节点上该文件的缓存失效,后续请求会重新从源站获取最新内容。
  3. 目录下多个文件更新:当更新涉及一个目录下的多个文件时,进行目录刷新。这样可以一次性让该目录下所有文件在 CDN 节点的缓存都失效,保证后续请求获取到的是最新的文件。
  4. URL 预热(可选):完成刷新操作后,若预计更新后的内容会有大量访问请求,可以进行 URL 预热。将更新后的内容提前加载到 CDN 节点的缓存中,以便用户访问时能直接从 CDN 节点快速获取,减少等待时间。

场景三:网站版本更新

网站进行版本更新,通常会涉及多个目录和文件的更改,操作顺序如下:

  1. 刷新操作
  2. 先进行目录刷新,针对那些有内容更新的目录,让 CDN 节点上这些目录下的所有缓存内容失效。
  3. 若还有个别不在更新目录中的文件也有更改,再对这些文件进行 URL 刷新。
  4. URL 预热:完成刷新后,对更新后的重要页面、核心资源等进行 URL 预热。确保在新版本上线后,用户能够快速访问到更新后的内容,提升用户体验。

注意事项

  • 操作频率限制:不同的 CDN 服务商对刷新和预热操作可能有频率和数量的限制,在进行操作前要了解清楚,避免因超过限制而导致操作失败。
  • 操作生效时间:刷新和预热操作都需要一定的时间才能完全生效,具体时间取决于 CDN 节点的分布和网络状况等因素。在操作完成后,可以通过访问相关内容来验证是否已经更新或预热成功。

针对源站做白名单设置

想法是在源站的网关层针对腾讯云 CDN 回源 ip 段做白名单限制。其他地址直接访问直接返回 403 错误。

调用接口查询回源IP白名单

参考:https://cloud.tencent.com/document/product/228/41954?from_column=20421&from=20421

调用接口获取最新节点信息,发现不支持查询。只能手动查找。

image-20250408165141525 image-20250408165231199

CDN控制台查询回源IP白名单

想法是在源站的网关层针对腾讯云 CDN 回源 ip 段做白名单限制。其他地址直接访问直接返回 403 错误。

1. 回源节点查询

登录 CDN 控制台,选择左侧菜单目录 → 回源节点查询。

将查询到的 IP 配置到源站 Caddy 的白名单中。 下载的 IP 段文件
image-20250408145712836 image-20250408145753133

2. 配置 Caddy 白名单

目录结构

# tree ./
./
├── allowed_ips.txt
└── Caddyfile

Caddyfile 文件

(ipwl) {
    @ip_whitelist {
        import allowed_ips.txt
    }

    route @ip_whitelist {
        reverse_proxy {args.0}
    }

    respond "Blocked" 403
}


*.linuxnbg.com linuxnbg.com {
    header Strict-Transport-Security "max-age=63072000"

    @yuan host yuan.linuxnbg.com
    import log yuan
    handle @yuan {
        import ipwl http://10.0.8.6:10001
    }

    handle_errors {
        @deploy expression `{err.status_code} in [502]`
        handle @deploy {
            respond "服务器欠电费了,请稍候"
        }
    }

    handle {
        abort
    }
}

allowed_ips.txt 文件

remote_ip 221.219.106.40 101.71.100.0/24 101.71.101.0/24 111.20.28.0/24 111.20.29.0/24 111.32.207.0/24 113.200.123.0/24 113.201.154.0/24 113.219.203.0/24 116.162.152.0/24 116.162.153.0/24 117.147.229.0/24 117.147.230.0/24 120.226.27.0/24 122.246.31.0/24 123.150.77.0/24 182.254.63.0/24 183.61.174.0/24 219.144.89.0/24 219.144.90.0/24 223.109.210.0/24 27.44.206.0/24 36.158.253.0/24 43.137.149.0/24 43.140.24.0/24

3. 查看效果

理想效果:除了 allowed_ips.txt 文件中获取的地址外,其他地址直接访问源站返回 403 错误。

实际效果:很可惜、过于理想化。回源还是显示 403。怀疑是回源节点查询出的 IP 段有遗漏。但是想到腾讯云不会犯如此低级的错误。继续排查,怀疑过 301/302 跳转问题,开始提工单。

发现 Cache Miss,回源操作后还是显示 403 假期前提交的,也没细看,打算假期后再看。
image-20250408153149271 image-20250408153958134image-20250408153917328

4. 排查问题

假期回来后,怀疑回源节点查询出的 IP 段有遗漏,访问的回源 IP 不在源站白名单内。再次提交工单。

我提问 腾讯云工程师回复
image-20250408160157623 image-20250408160559977
image-20250408160712509

自信地回答,第一时间没有去排查这个问题,排查了很多问题后,决定打开源站日志进行分析。

caddy 文件中添加 log

(log) {
    log {
        output file /var/log/caddy/{args[0]}/access.log {
            roll_size 100MiB
            roll_local_time
            roll_keep_for 168h
            roll_uncompressed
        }
        format filter {
            wrap console {
                time_local
                time_format wall
                duration_format ms
            }
            request>headers delete
            request>remote_ip delete
            request>remote_port delete
            request>host delete
            request>tls delete
            resp_headers delete
            bytes_read delete
            user_id delete
        }
    }
    @skip path_regexp \.(js|css|png|jpe?g|gif|ico|woff2?|otf|ttf|eot|svg|txt|pdf|docx?|xlsx?)$
    log_skip @skip
}


    @yuan host yuan.linuxnbg.com
    import log cdn-test # 添加导入日志配置

查看 caddy 日志后发现有地址失败并返回了 403 状态码。

caddy 日志发现 219.144.88.173 请求返回 403
image-20250408161618766

5. 发现问题

查询归属发现为腾讯云 CDN 节点 查询该节点并未在回源节点中,真相大白。回复工单。
image-20250408161740994 image-20250408162048659
我提问 腾讯云工程师回复
image-20250408162548004 image-20250408162642259

6. 总结

腾讯云获取回源节点个别机房出口 IP 上报接口异常导致没上报完整。这种问题出现在知名云厂商并且是收费的功能,很不应该,信任度降级。感觉基于 IP 段做白名单此功能很不稳定。尝试使用其他方法。基于特定 Header 的请求访问限制。

想法是在腾讯云 CDN 的回源配置里添加一个名为 cdn:hcc 的 HTTP 头参数。源站会依据该 HTTP 头中的 cdn:hcc 参数进行白名单限制。如果请求未携带此参数,或者携带的参数不符合白名单要求,源站会直接返回 403 状态码,表示禁止访问。

1. 设置特定的 header

查询文档: https://cloud.tencent.com/document/product/228/45078

腾讯云 CDN 回源配置新增一个新的 HTTP 头部参数 “cdn:hcc”
image-20250408171706076

2. 配置 Caddy 白名单

目录结构

# tree ./
./
└── Caddyfile

Caddyfile 文件

yuan.linuxnbg.com {
    @invalid_origin {
        not header cdn hcc
    }
    respond @invalid_origin "Only CDN origin requests are allowed" 403
    reverse_proxy 127.0.0.1:10001 # 后端服务地址
}

3. 验证

使用以下 curl 命令来测试不同情况:

未携带头

curl https://linuxnbg.com

此请求会匹配 @invalid_origin,返回 403 状态码。
image-20250408173526237

携带错误的头值

curl -I -H "test:test" https://yuan.linuxnbg.com

此请求同样会匹配 @invalid_origin,返回 403 状态码。
image-20250408173919198

携带正确的头值

curl -I -H "cdh:hcc" https://yuan.linuxnbg.com

此请求应该能够正常访问后端服务,返回状态码 200。
image-20250408173724847

基于自定义回源 header 白名单成功了,但是遇到个新问题

4. 新问题

每次对 CDN 相关设置进行变更后,CDN 都会自动重新部署。然而,在部署完成之后,访问网站主页时就会出现异常状况。每个客户端打开页面会发起频繁的请求,在 1 秒内就会产生大量请求,而且只要不手动取消,请求就会持续不断。腾讯 cdn 这边会一直回源,会消耗很多流量。

按照我源站的日志看有异常、为了不浪费时间、遇事不决可提工单。
img
提交工单,询问
image-20250408175325374
建议加黑名单有点抽象 我总不能把每个客户端都拉黑吧
image-20250408175429614
看回答我很懵逼,我学识浅薄,感觉没必要浪费时间,再次刷新所有目录缓存后解决。暂时解决这个。设置了流量阈值暂时可以接受。
image-20250408175651106

贴一段日志看看怎么分析客户端

20250408135025 123.125.10.3 linuxnbg.com /search/search_index.json 467056 22 26 200 https://linuxnbg.com/ 1227 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "(null)" GET HTTPS miss 58043
20250408135026 123.125.10.3 linuxnbg.com /css/custom.css 154 22 26 200 https://linuxnbg.com/ansible/00-ansible-about/ 1 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "(null)" GET HTTPS hit 58043
20250408135026 123.125.10.3 linuxnbg.com /css/custom.css 155 22 26 200 https://linuxnbg.com/ 1 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "(null)" GET HTTPS hit 58043
20250408135026 123.125.10.3 linuxnbg.com /search/search_index.json 229488 22 26 200 https://linuxnbg.com/ 1244 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "(null)" GET HTTPS miss 58043
20250408135026 123.125.10.3 linuxnbg.com /assets/stylesheets/palette.06af60db.min.css 2003 22 26 200 https://linuxnbg.com/ansible/00-ansible-about/ 2 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "(null)" GET HTTPS hit 58043
20250408135026 123.125.10.3 linuxnbg.com /assets/stylesheets/palette.06af60db.min.css 2003 22 26 200 https://linuxnbg.com/ 1 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "(null)" GET HTTPS hit 58043
20250408135026 123.125.10.3 linuxnbg.com /assets/stylesheets/main.45e1311d.min.css 21749 22 26 200 https://linuxnbg.com/ansible/00-ansible-about/ 2 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "(null)" GET HTTPS hit 58043
20250408135026 123.125.10.3 linuxnbg.com /assets/stylesheets/main.45e1311d.min.css 21750 22 26 200 https://linuxnbg.com/ 2 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "(null)" GET HTTPS hit 58043
20250408135025 123.125.10.3 linuxnbg.com / 114485 22 26 200 https://linuxnbg.com/ 2 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "(null)" GET HTTPS hit 58043

总结

都是按照官方文档操作的 , 整体下来虽然过程曲折 , 但是结果还是实现了

后续测试使用其他 cdn 看看效果。