Self-built blog address: www.bytelife.net, welcome to visit! For a better reading experience, I suggest you go to my blog 👇

In this paper, the author: Jeffrey this article links: www.bytelife.net/articles/47… Copyright Notice: All articles on this blog are licensed BY-NC-SA unless otherwise stated. Reprint please indicate the source!


Recently, the blog to Tencent cloud, compared Tencent cloud and Ali cloud, found that Tencent cloud CDN recently made a lot of upgrades, for THE CDN cache node configuration is more detailed, after all, Tencent cloud price is lower, more friendly to personal webmaster. This article mainly discusses how to use COS+CDN of Tencent Cloud to deploy static websites, and how to use Tencent cloud function service to perfectly solve the automatic cache refresh problem of CDN nodes (some optimization of the refresh function provided by the official).

My deployment plan

  • Operating environment: Site use of domestic and overseas separate parse solution, resolves to tencent cloud CDN node, in overseas parsing to Vercel CDN nodes, while the main access site is due to domestic users, but Google, bing and so on, after all, the search engine is abroad, and the acceleration of CDN for foreign and domestic is more expensive, so will be separate parsing.
    • China: Tencent Cloud COS object storage + Tencent cloud CDN acceleration
    • Overseas: Vercel static web hosting
  • Automated deployment: Since the source code of the site is hosted on GitHub, so using GitHub Actions for automated deployment, after writing the article directly push can automatically deploy to multiple platforms, it is not too convenient.

GitHub Actions are automatically deployed to Tencent Cloud COS

Tencent Cloud provides a very useful CLI tool that can quickly upload files to COS object storage by executing some simple commands. In the Git project under the root directory of the creation. Making/workflows/XXX. Yml file, you can create a configuration of the Actions. Hexo can be deployed to Tencent Cloud COS object storage using the following configuration:

# 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: The ${{ secrets.TENCENT_SECRET_ID }}
        SECRET_KEY: The ${{ secrets.TENCENT_SECRET_KEY }}
        BUCKET: The ${{ 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/ / -fCopy the code

Among them:

  • ${{ secrets.TENCENT_SECRET_ID }},${{ secrets.TENCENT_SECRET_KEY }},${{ secrets.TENCENT_COS_BUCKET }}This needs to be configured in the Github repository secrets Settings.
  • The commandcoscmd upload -rs --delete ./public/ / -fCompare the files in the COS bucket and update them if they change. Delete the files if they exist in the COS bucket but not in the public directory.coscmdThe specific use method can refer toOfficial document of Tencent Cloud.

Enable the COS static website function

Uploading the website file to COS is not enough. You need to enable the static website function of COS, open the bucket -> Basic Configuration -> Static Website, and configure it as shown in the following figure:

At this point, you can access the website by using the domain name provided by the access node in the figure, and of course you can bind the custom domain name, provided that the domain name has been registered.

Tencent Cloud CDN acceleration

Create a domain name

If your domain name is registered, you can also use Tencent Cloud CDN to accelerate COS static website. The configuration is very simple. Create a domain name in the CDN page and configure it as shown in the following figure:

Configure the cache

The cache configuration is very important. As the site is a static site, the content of the site changes little. In order to reduce the CDN return request, the node cache policy must be configured.

Note: There is no need to worry about the page being unable to update if the node cache time is set too long. I will explain how to configure automatic refresh of the cache later.

More details about CDN configuration will not be discussed, but are very simple and easy to understand.

CDN node cache is automatically refreshed

The official plan

As the CDN node cache policy is configured in the previous step, as long as the request can hit the cache, the source request will not be returned, which will lead to our page update cannot be displayed to users in a timely manner. Therefore, we need to consider how to automatically refresh the CDN node cache.

Tencent Cloud officially provides us with a solution. You can configure a function in function calculation of COS bucket ->CDN cache refresh function, as shown in the following figure:

But this scheme, there is a problem because of our static web sites have default index page index. The HTML, and this function is provided by the official URL will only refresh the corresponding files, and do not refresh the index URL, for example http://www.bytelife.net/index.html this file, Usually our request is http://www.bytelife.net/, so the official solution is not perfect for static sites.

Optimization scheme

You can solve this problem by simply modifying the official function. Click on the function name in the CDN cache refresh function list to jump to the edit page of the function:

Replace the contents of the index.js file with the following code and click the “Deploy” button in the upper right corner:

'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 = [];
    // The main changes are in this location
    cdnHosts.forEach(host= > {
      const tempUrl = getObjectUrl({
        cosInstance,
        bucket,
        region,
        key,
        origin: `The ${/^(http\:\/\/|https\:\/\/)/.test(host) ? ' ' : 'https://'}${host}`
      });
      purgeUrls.push(tempUrl);
      // If it ends in /index.html, add the home page of the directory /
      Increase / / such as 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 = awaittask.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('; ')}}Copy the code