个人博客搭建全记录04- CDN 部署与缓存清除完整指南

前情提要

在之前的博客搭建过程中,我采用了 Typora+图床的写作协作模式。当时图床直接使用”公有读、私有写”的配置方案,这种方式存在明显的流量盗刷风险。更安全的优化方案:将图床调整为”私有读写”模式,通过授权 CDN 访问图床资源,最终完成 CDN 的部署落地。
与此同时,为了提升各地用户访问博客的加载速度,优化整体浏览体验,引入 CDN 加速方案也成为核心需求。恰好我在购买服务器时,一并选购了腾讯云 EdgeOne 服务,一年期的费用也还划算,因此直接基于该服务实现 CDN 加速部署。

一、什么是 CDN

首先,我们需要知道用户在浏览器输入地址发生了什么,以下是经过简化的过程

image-20251227213048636

当用户输入网址后,首先由 DNS 服务器解析该域名对应的 IP 地址;接着,用户设备与该 IP 地址对应的源服务器建立连接;源服务器处理请求后,将网站数据返回给用户浏览器;最后,浏览器解析数据并渲染出完整网页。

从这个流程可以看出,传统访问模式下,用户需直接与源服务器进行数据交互。无论用户身处何地,数据都要从源服务器长途传输,这会不可避免地产生网络延迟。试想一下,如果能像物流配送系统一样,在离用户最近的地方设置一个”中转站”,直接向用户分发所需内容,访问速度是不是会大幅提升?这正是 CDN 的核心设计思路。

CDN,全称是 Content Delivery Network,即内容分发网络。它是由分布在全球各地的服务器集群组成的网络架构,核心目标是将网站的图片、视频、软件安装包等内容,提前缓存到离用户更近的边缘节点服务器上,让用户能从最优节点快速、可靠地获取所需内容。

CDN 的核心工作原理

  1. 缓存:CDN 运营商会把源站(你的服务器)上的静态内容(图片、CSS、JS、视频、安装包等)复制一份,存储到全球各地的边缘节点服务器上。
  2. 智能调度:当用户请求访问你的网站时,CDN 的调度系统会通过技术手段(如分析用户 IP 地址)判断哪个边缘节点离用户最近、响应最快。
  3. 就近访问:将用户的请求引导至那个最优的边缘节点。用户直接从该节点获取内容,无需千里迢迢回源站索取。
  4. 回源:如果边缘节点上没有用户请求的内容,它会去源站拉取,缓存到本地后再提供给用户。

使用 CDN 的主要好处

  1. 极大提升访问速度:这是最核心的好处。用户直接从附近的节点获取数据,延迟大大降低,网页打开速度、视频加载速度显著提升。
  2. 减轻源站压力:绝大多数请求都被边缘节点处理了,源站服务器的带宽、计算压力大幅下降,成本也更低,更不容易因流量暴增而宕机。
  3. 提高可用性与稳定性:CDN 网络具有多节点、冗余的特性。即使某个节点或线路出现故障,流量会自动切换到其他正常节点,保障服务不中断。
  4. 增强安全性:CDN 可以作为一道防护屏障,帮助抵御分布式拒绝服务攻击等网络攻击,因为攻击流量会先被分散到各个边缘节点,不会全部冲向源站。
  5. 节省带宽成本:源站输出的总流量减少,相应的带宽费用也会降低。

什么内容适合用 CDN?

主要是静态内容

  • 网站静态资源:图片、样式表、JavaScript 文件、字体
  • 软件安装包、应用程序更新
  • 音视频流媒体(点播和直播)
  • 游戏补丁下载

对于频繁变化的动态内容(如实时查询、用户个人数据),CDN 主要优化其传输路径,而非缓存内容本身。

二、具体操作

图床配置

图床 CDN 配置的核心是在 EdgeOne 中添加子域名,并将其与腾讯云 COS 存储桶关联,实现 CDN 对私有存储桶的授权访问。

这一步跟着提示配置即可

这一步骤按照控制台的引导流程操作即可完成。需要注意的是,由于我新增了用于图床的子域名,因此需要在 DNS 服务中添加对应的解析记录,确保域名能正确指向 CDN 节点。

如果已申请 SSL 证书,可在配置过程中一并部署,实现图床资源的 HTTPS 安全访问。配置完成后,可直接输入图床子域名访问测试,若能正常加载存储桶中的图片,说明 CDN 访问 COS 存储桶的配置已生效。

如果这时候能够正常加载出来图片则说明已经正常完成 CDN 访问 COS 存储桶

网站配置

也是与图床类似,不同是原站配置选择IP/域名,填写自己的服务器 ip

三、CDN 缓存处理

使用 CDN 加速后,用户访问的是边缘节点缓存的内容。这会带来一个问题:当我们将更新后的代码推送到源站服务器后,用户访问时可能仍看到旧内容,因为 CDN 节点的缓存尚未更新。因此,我们需要在网站部署完成后,同步执行 CDN 缓存清除操作。

清除缓存的接口可以参照 EdgeOne 的官方文档

新建 api 密钥

访问方式记得勾选编程访问

创建完成后的密钥记得妥善保存

配置缓存清除参数

deploy.config.js创建腾讯云 CDN 缓存清除配置

cdnPurge: {
    zoneId: 'your-zone-id', // 站点ID,可在腾讯云控制台获取
    type: 'purge_host', // 缓存清除类型:purge_url, purge_prefix, purge_host, purge_all, purge_cache_tag
    targets: ['yuangis.site', 'www.yuangis.site'], // 需要清除缓存的目标列表
    secretId: 'your-secret-id', // 腾讯云API密钥ID
    secretKey: 'your-secret-key', // 腾讯云API密钥密钥
  },

清除缓存的类型

  • purge_url : URL 刷新

  • 清除指定完整 URL 的缓存资源

  • 适用场景:需要精确清除单个或少量特定文件的缓存

  • 示例: https://www.example.com/a.txt

  • purge_prefix : 目录刷新

  • 清除指定目录路径下的所有缓存资源

  • 适用场景:需要清除某个目录下的所有文件缓存

  • 示例: https://www.example.com/images/

  • purge_host : Hostname 刷新

  • 清除指定域名下的所有缓存资源

  • 适用场景:需要清除整个域名的缓存

  • 示例: yuangis.site 或 www.yuangis.site

  • purge_all : 站点下全部缓存刷新

  • 清除整个站点(ZoneId 对应的站点)的所有缓存资源

  • 适用场景:需要全面更新站点内容,清除所有缓存

  • purge_cache_tag : cache-tag 刷新

  • 根据资源的 cache-tag 标签清除缓存

  • 适用场景:需要批量清除带有特定标签的资源缓存

  • 需要额外提供 CacheTag 参数

创建清除缓存脚本

const config = require('../deploy.config.js')

// 导入腾讯云TEO SDK
const tencentcloud = require('tencentcloud-sdk-nodejs-teo')
const TeoClient = tencentcloud.teo.v20220901.Client

// 配置客户端
const clientConfig = {
  credential: {
    secretId: config.cdnPurge.secretId,
    secretKey: config.cdnPurge.secretKey,
  },
  region: 'ap-guangzhou', // TEO服务默认区域
  profile: {
    httpProfile: {
      endpoint: 'teo.tencentcloudapi.com',
    },
  },
}

// 创建客户端实例
const client = new TeoClient(clientConfig)

// 发送CDN缓存清除请求
async function purgeCdnCache() {
  console.log('⏳ 开始执行CDN缓存清除...')

  // 业务参数
  const params = {
    ZoneId: config.cdnPurge.zoneId,
    Type: config.cdnPurge.type,
    Targets: config.cdnPurge.targets,
  }

  try {
    // 发送请求
    const response = await client.CreatePurgeTask(params)
    console.log('📝 CDN缓存清除API响应:', JSON.stringify(response, null, 2))

    if (response.Response) {
      const result = response.Response
      console.log('✅ CDN缓存清除请求已提交')
      console.log(`📋 任务ID: ${result.JobId}`)

      if (result.FailedList && result.FailedList.length > 0) {
        console.log('⚠️  部分任务失败:')
        result.FailedList.forEach((fail) => {
          console.log(`   - ${fail.Target}: ${fail.Reason}`)
        })
      } else {
        console.log('🎉 所有缓存清除任务提交成功')
      }
    }
  } catch (error) {
    console.error('❌ CDN缓存清除失败:')
    if (error.code) {
      console.error(`   - 错误代码: ${error.code}`)
      console.error(`   - 错误信息: ${error.message}`)
    } else {
      console.error(`   - ${error.message}`)
    }
    throw error
  }
}

// 导出函数,供其他脚本调用
module.exports = purgeCdnCache

// 如果直接运行该脚本,则执行清除操作
if (require.main === module) {
  purgeCdnCache().catch((err) => {
    process.exit(1)
  })
}

集成到部署流程

// 部署完成后清除CDN缓存
if (config.cdnPurge) {
  try {
    const purgeCdnCache = require('./cdn-purge');
    await purgeCdnCache();
  } catch (purgeError) {
    console.error('⚠️  CDN缓存清除失败,但部署已完成:', purgeError.message);
  }
}

执行部署与缓存清除

运行

pnpm run fastdeploy

四、参考文章

https://cyanfish.site/8c678423.html?highlight=cdn

https://cyanfish.site/d5962236.html?highlight=cdn