自建博客地址: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对象存储:
# workflowname: Blogon: push: branches: - masterjobs: 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('; ') }}