网站内容更新方案(腾讯云和阿里云后:CDN缓存节点的缓存自动刷新 )

优采云 发布时间: 2021-11-08 09:00

  网站内容更新方案(腾讯云和阿里云后:CDN缓存节点的缓存自动刷新

)

  我最近把我的博客扔到了腾讯云。对比了腾讯云和阿里云,发现腾讯云最近对CDN做了很多升级。CDN缓存节点的配置比较详细。另外,腾讯云更便宜,适合个人站长。更友好。本文文章主要讲如何使用腾讯云的COS+CDN部署静态网站,并使用腾讯云功能服务完美解决(对官方刷新功能做了一些优化)CDN节点缓存自动刷新问题。

  自动部署我的部署计划:由于站点的源代码托管在GitHub上,所以我使用GitHub Actions进行自动部署。写完文章直接push up,就可以自动部署到多个平台,不太方便。GitHub Actions 自动部署到腾讯云 COS

  腾讯云提供了一个非常实用的cli工具,你可以通过执行一些简单的命令,快速上传文件到COS对象存储。在 Git 项目的根目录创建一个 .github/workflows/xxx.yml 文件来创建一个 Actions 配置。

  使用以下配置将 Hexo 部署到腾讯云 COS 对象存储:

  # workflow

name: Blog

on:

push:

branches:

- master

jobs:

deploy:

name: Deploy Blog

runs-on: ubuntu-latest

env:

TZ: Asia/Shanghai

steps:

# check it to your workflow can access it

# from: https://github.com/actions/checkout

- name: Checkout Repository master branch

uses: actions/checkout@v2

with:

ref: 'master'

submodules: true

# from: https://github.com/actions/setup-node

- name: Setup Node.js

uses: actions/setup-node@master

with:

node-version: "14.x"

- name: Yarn Install Cache

uses: c-hive/gha-yarn-cache@v1

- name: Install Dependencies

run: yarn install

## generate files

- name: Generate Hexo Site Public Files & Create Files for Blog Assets

run: yarn build

## deploy to tencent cos

- name: Deploy to Tencent COS

env:

SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}

SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}

BUCKET: ${{ secrets.TENCENT_COS_BUCKET }}

REGION: ap-shanghai

run: |

sudo pip install coscmd

coscmd config -a ${SECRET_ID} -s ${SECRET_KEY} -b ${BUCKET} -r ${REGION}

coscmd upload -rs --delete ./public/ / -f

  在:

  启用COS静态网站功能

  将 网站 文件上传到 COS 是不够的。需要开启COS的静态网站功能,打开bucket -> Basic Configuration -> Static 网站,如下图配置:

  

  这时候就可以通过图中接入节点提供的域名访问网站。当然也可以绑定自定义域名,前提是域名已经备案。

  腾讯云CDN加速域名创建

  如果您的域名已经备案,还可以使用腾讯云CDN加速COS静态网站。配置非常简单。在CDN页面创建一个域名,如下图配置:

  

  配置缓存

  缓存配置非常重要。由于站点是静态站点,网站的内容变化较少。为了减少CDN的回源请求,必须配置节点缓存策略。可以参考我的配置如下,其中浏览器缓存可以点击需要配置:

  

  注意:不用担心节点缓存时间配置过长导致页面无法更新。后面我会讲如何配置缓存的自动刷新。

  关于 CDN 配置的更多细节我不再赘述。

  CDN节点缓存自动刷新官方方案

  由于上一步配置了CDN节点的缓存策略,只要请求能命中缓存,就不会进行回源请求。这会导致我们的页面更​​新不能及时展示给用户,所以我们需要考虑如何缓存CDN节点自动刷新。

  腾讯云官方为我们提供了解决方案。可以在COS桶的函数计算->CDN缓存刷新函数中配置一个函数。可以参考下图所示的配置:

  

  但是这个解决方案有一个问题。由于我们静态的网站有一个默认的索引页index.html,所以官方的函数只会刷新对应文件的URL,不会刷新索引URL,比如这个文件。通常我们的要求是,所以官方的解决方案对于静态网站并不完美。

  优化

  这个问题可以通过简单的修改官方函数来解决。点击刚刚创建的CDN缓存刷新函数列表中的函数名称,跳转到该函数的编辑页面:

  

  将index.js文件的内容替换成如下代码,最后点击右上角的“Deploy”按钮:

  'use strict'

const CosSdk = require('cos-nodejs-sdk-v5')

const CdnSdk = require('./common/CdnSdk')

const CdnRefreshTask = require('./common/CdnRefreshTask')

const {

getParams,

getObjectUrl,

logger,

getLogSummary

} = require('./common/utils')

exports.main_handler = async (event, context, callback) => {

/**

* parse param from event and process.env

*/

const { objects, cdnHosts, secretId, secretKey, token } = getParams(event)

logger({

title: 'param is parsed success, param as follow: ',

data: { objects, cdnHosts, event }

})

/**

* init cos instance

*/

if (!secretId || !secretKey || !token) {

throw new Error(`secretId, secretKey or token is missing`)

}

const cdnSdkInstance = new CdnSdk({ secretId, secretKey, token })

const cosInstance = new CosSdk({

SecretId: secretId,

SecretKey: secretKey,

XCosSecurityToken: token

})

const taskList = objects.map(({ bucket, region, key }) => {

const purgeUrls = [];

// 主要变更内容在这个位置

cdnHosts.forEach(host => {

const tempUrl = getObjectUrl({

cosInstance,

bucket,

region,

key,

origin: `${/^(http\:\/\/|https\:\/\/)/.test(host) ? '' : 'https://'}${host}`

});

purgeUrls.push(tempUrl);

// 如果以 /index.html 结尾,则增加目录首页/

// 例如 https://www.xxxx.com/index.html, 则增加 https://www.xxxx.com/

if(tempUrl.lastIndexOf('/index.html') == (tempUrl.length - 11)){

purgeUrls.push(tempUrl.substr(0, tempUrl.length - 10))

}

});

return new CdnRefreshTask({

cdnSdkInstance,

urls: purgeUrls

})

})

const taskResults = []

for (const task of taskList) {

const results = await task.runPurgeTasks()

taskResults.push(...results)

}

logger({

title: 'cdn refresh full logs:',

data: taskResults

})

const { status, messages } = getLogSummary(taskResults)

logger({

messages: messages.map(item => item.replace(/\,\ /g, '\n'))

})

if (status === 'fail') {

throw messages.join('; ')

} else {

return messages.join('; ')

}

}

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线