关于hexo:Hexo静态网站托管到腾讯云COSCDN加速以及缓存自动刷新完美方案

61次阅读

共计 4251 个字符,预计需要花费 11 分钟才能阅读完成。

自建博客地址:https://www.bytelife.net,欢送拜访!本文为博客同步发表文章,为了更好的浏览体验,建议您移步至我的博客👇

本文作者:Jeffrey
本文链接:https://www.bytelife.net/articles/47472.html
版权申明:本博客所有文章除特地申明外,均采纳 BY-NC-SA 许可协定。转载请注明出处!


近期把博客折腾到腾讯云了,比照了腾讯云和阿里云后,发现腾讯云近期 CDN 做了很多降级,对于 CDN 缓存节点的配置更加粗疏,另外毕竟腾讯云价格更低嘛,对集体站长更敌对一些。这篇文章次要讲讲如何应用腾讯云的 COS+CDN 部署动态网站,以及应用腾讯云函数服务完满解决(对官网提供的刷新函数做了些优化)CDN 节点的缓存主动刷新问题。

<!–more–>

我的部署计划

  • 运行环境:站点解析采纳境内和境外离开解析的计划,境内解析到腾讯云的 CDN 节点,境外解析到 Vercel 的 CDN 节点,尽管站点的次要拜访因为就是国内用户,但毕竟谷歌、必应等等搜索引擎都是国外的,而国内 CDN 对于境外的减速又比拟贵,所以就离开解析啦。

    • 境内:腾讯云 COS 对象存储 + 腾讯云 CDN 减速
    • 境外:Vercel 动态网站托管
  • 自动化部署:因为站点的源码托管在 GitHub 下面,所以应用 GitHub Actions 进行自动化部署,写完文章间接 push 下来就能够主动部署到多个平台,几乎不要太不便。

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

其中:

  • ${{secrets.TENCENT_SECRET_ID}}${{secrets.TENCENT_SECRET_KEY}}${{secrets.TENCENT_COS_BUCKET}}须要在 github 仓库的 secrets 设置中进行配置。
  • 命令 coscmd upload -rs --delete ./public/ / -f 的意思是比拟以后 COS 存储桶内的文件,如果产生变更则更新,如果存储桶中存在但 public 目录中不存在,则删除对应的文件,coscmd的具体应用办法能够参考腾讯云官网文档。

开启 COS 动态网站性能

将网站文件上传到 COS 还不够,须要开启 COS 的动态网站性能,关上 存储桶 -> 根底配置 -> 动态网站,依照下图所示进行配置:

这时就能够通过图中的拜访节点提供的域名来拜访网站了,当然也能够绑定自定义域名,前提是域名曾经备案。

腾讯云 CDN 减速

创立域名

如果你的域名有备案的话,同时能够应用腾讯云 CDN 减速 COS 动态网站,配置非常简略,在 CDN 页面中创立一个域名,按下图所示进行配置:

配置缓存

缓存配置非常重要,因为站点是动态站点,网站的内容变动比拟少,为了升高 CDN 的回源申请,肯定要配置节点缓存策略,能够参考我的配置如下,其中浏览器缓存能够按需配置:

留神:这里不必放心节点缓存工夫配置的过长会导致页面无奈更新,前面我会讲如何配置缓存的主动刷新。

对于 CDN 配置的更多细节就不讲了,都很简略,一看就懂。

CDN 节点缓存主动刷新

官网计划

因为上一步中配置了 CDN 节点的缓存策略,申请只有可能命中缓存,就不会进行回源申请了,这会导致咱们的页面更新不能及时的展示给用户,因而须要思考如何进行 CDN 节点的缓存主动刷新。

腾讯云官网给咱们提供了一个解决方案,能够在 COS 存储桶的 函数计算 ->CDN 缓存刷新函数 中配置一个函数,可参考下图所示配置:

但这个计划存在一个问题,因为咱们的动态网站有默认索引页面 index.html,而官网提供的这个函数只会刷新对应的文件的 URL,而不会刷新索引 URL,例如 http://www.bytelife.net/index.html 这个文件,通常咱们的申请是http://www.bytelife.net/,因而官网的计划针对于动态网站来说不算完满。

优化计划

能够通过简略批改官网的函数来解决这个问题,点击刚刚创立的 CDN 缓存刷新函数 列表中的函数名称,能够跳转的函数的编辑页面:

将 index.js 文件内容替换为上面的代码,最初点击右上角的“部署”按钮即可:

'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