零成本搭建现代博客之优化国内访问速度

本文属于零成本搭建现代博客指南系列第五篇【优化国内访问速度篇】。

更新自2022年04月15日

最近将博客部署的CDN从Vercel更换为Cloudflare Pages,从测试的结果以及用户的反馈看,国内访问的速度更快了(如果你所在的地区响应很慢,请留言告知)。

现在的博客架构图如下:

这个旧图并没有体现出网站部署到Cloudflare Pages,目前Vercel唯一的作用是将bmpi.dev的请求301重定向到www.bmpi.dev(域名在AWS Route53上管理),实际静态页面是从Cloudflare Pages获取的。

所以用户的请求实际上是这样的:

Browser -> bmpi.dev -> AWS Route53 -> Vercel -> www.bmpi.dev -> Cloudflare Pages

更新自2020年12月29日


在V2EX发了该篇文章的帖子优化托管在国外博客的国内访问速度后,一些回复中多次提到使用 vercel 部署的站在国内访问速度很快,而阿里云会产生如下问题:

阿里云国际版 CDN 就算你解析到香港或者新加坡这种带 CN2 地方,CDN 的 IP 过几天就会被墙,阿里可不会因为 IP 被墙而换 IP,毕竟没有保证CDN国外节点能够在国内访问。而且你现在还没手动解析到带 CN2 的 IP,现在命中的阿里 CDN 新加坡的路由简直可以说是绕了地球一圈。(电信测试)(@mason961125)

帖子回复中很多电信用户根本打不开网站,经路由测试某些地区是绕了一大圈,甚至到欧洲后再转发到新加坡,经过一番测试后我决定把网站迁移至 vercel。也考虑过 cloudflare CDN ,虽然速度在国内挺一般,但是比阿里云 CDN要快。最终因为cloudflare要求必须托管域名的DNS,而我的域名托管至AWS Route53,此域名设置了很多其他的DNS记录,迁移起来成本过高,还涉及到证书的问题,所以放弃了。

博客迁移至 vercel 过程

  1. 本博客仓库部署在 bmpi-dev/bmpi-dev,而vercel要求个人用户的仓库必须来自个人用户,所以我只能 fork 至我的个人仓库 madawei2699/bmpi.dev 部署。考虑到一些原仓库有一些链接已经在使用了,所以我做了两个仓库间自动同步,具体可见此 GitHub Actions,之后以个人仓库为主仓库推送代码。

  2. 域名DNS修改。在vercel设置好域名后,它会自动申请HTTPS证书,之后在AWS Route53DNSCNAME指向其配置记录即可。同时需要做一些主域名跳转至www域名的设置,还有强制浏览器使用HTTPS等设置。vercel默认还启用了OCSP Stapling (可忽略证书校验,加速网站 HTTPS 访问)。

  3. SEO的影响。vercel在每次部署后都会生成一个随机预览链接,这个链接在请求响应里已经做了x-robots-tag: noindex,提示Google爬虫不要索引此页面,这点是很好的。但是它默认还给了两个域名链接,并且每次在git commit中评论附上此链接,而这个两个链接并没有noindex的设置,爬虫会直接索引此页面,进一步导致内容重复的问题。考虑到我的主站已经被Google索引了一段时间,此首页重复的问题对网站的影响倒不大。但是我还是无法理解这种设计,希望vercel能够在后续改进下。

  4. 由于本站使用了hugo 0.61.0构建,所以添加了vercel.json配置hugo版本,同时在页面配置中指定了构建命令hugo --gc && node _tools/newpostcheck.js,这样在构建的时候可以触发新文章浏览器推送通知的功能。

  5. 网站测速结果。测速结果来自17ce.com/boce.com/ce8.com

以下是旧文,仅供参考


构建我的被动收入网站部署在Netlify CDN上,我在零成本搭建现代博客之加载速度优化篇这篇文章中对它做了大量的基础技术性加载速度优化。最终达到在 Google PageSpeed Insights 上PC端98分的评分:

但是由于Netlify CDN在国内的访问速度并不好,导致国内用户访问速度非常的慢,甚至不可用。为了优化国内的访问速度,需要通过CDN给国内用户加速。

博客架构

为了更好的分析这个问题,我画了本博客的网络架构图:

优化前

  • Step 1.1: 本地写完文章后,推送到 BMPI.dev GitHub Repository
  • Step 1.2: Netlify 在检测到 GitHub 推送的Commit后,触发Deploy流水线,把此次变更发布自动上线。
  • Step 2.1: 本博客的DNS解析托管在AWS Route53服务上,当用户请求https://www.bmpi.dev,浏览器在解析过程中根据默认的配置找到了Netlify CDN地址,最终获取到了网站内容。

问题分析

国内用户访问网站慢的原因是,国内电信出口链路到Netlify CDN最近的边缘节点(新加坡digitalocean)延迟高,可能是其节点对国内链路没有做优化。

如果能使用支持国内网络的CDN或针对国内链路做优化的国际CDN,则能提高国内用户的访问加载速度,根据这篇提升你的外国服务器网站国内访问速度里提到的:

利用阿里云海外CDN,中国访客大部分会解析到亚太一区节点,而亚太一区CDN节点到中国大陆的线路大部分都经过了优化(香港节点和新加坡节点为三网GIA),而节点到源站服务器的线路又没有经过我国运营商国际出口,没有审查所以速度本来就不会太慢。

那么可以通过给网站配置阿里云CDN,在AWS Route53配置基于地理位置DNS路由策略,将国内的请求转发至阿里云CDN,将国外的请求转发至Netlify CDN。如下图的DNS配置:

考虑到备案的复杂性(内容审查及流程繁琐),我使用了阿里云CDN全球(不含中国)的加速配置(只要加速地区包含中国,所加速的域名必须做备案,但是本博客的域名托管至国外且顶级域名为dev,这种小众域名在国内还不能备案),国内用户的请求最终由阿里云新加坡节点服务,而阿里云新加坡的节点到国内相比Netlify CDN是做过链路优化的。

优化后

如博客架构图所示,加入了红框中的Step 2.3后,我们可以基于DNS路由策略将不同区域的用户请求转发至不同的CDN

优化过程

  1. 配置阿里云CDN。具体过程见提升你的外国服务器网站国内访问速度必须注意加速域名不能和源站域名相同,所以需要在Netlify上重新部署一个相同的网站(网址不同)作为CDN源站,同时需要考虑屏蔽爬虫爬取CDN源站,防止内容重复。考虑到此网址未公开,搜索引擎无法通过其他网址爬取此网址,所以不做爬虫屏蔽也可以。

  2. 需要在DNS配置基于位置的路由策略。中国区流量分配至阿里云CDN,其他默认流量分配给Netlify CDN

  3. HTTPS证书。需手动在阿里云上申请免费证书给CDN域名使用,同时下载此证书配置给Netlify使用。过期前需要重新申请证书并更新。

  4. HTTPS加速。如下图所示,HTTPSTLS的加解密是个耗时的过程,更不要说浏览器还需要校验证书的合法性。在这篇高性能 Nginx HTTPS 调优 - 如何为 HTTPS 提速 30%中,提到了一些优化HTTPS的手段,这些优化的设置在阿里云CDN中都可以设置。

  • 开启HTTP/2: HTTP/2 中可以在一个连接中进行并行多个请求。
  • 调整Cipher优先级: 尽量挑选更新更快的 Cipher,有助于减少延迟。
  • 启用OCSP Stapling: 忽略证书验证,能加快与网站连接速度。
  • 调整ssl_buffer_size: 如果是Rest API服务器,则有必要调整小此值。
  • 启用SSL Session缓存: 启用SSL Session缓存可以大大减少TLS的反复验证,减少TLS握手的 roundtrip。

阿里云CDN中可做如下设置优化:

  1. 测试不同地区用户访问的CDN

如果响应头里看到server: Netlify,则请求是到Netlify CDN的。

如果看到server: Tengine,则请求是到阿里云CDN的。

  1. 网站线路测速:

看起来国内不同地区访问速度相差还是挺大的,考虑到测速网站本身的机房网络问题,与实际用户访问的速度差异估计不同。

阿里云CDN国内用户访问不同地区的平均响应时间:

总结

经过此番优化,最终本站获得了如下的优势:

  • 网站源内容在国外CDN托管;
  • 域名在国外AWS Route53托管;
  • 网站无需备案与内容审查;
  • 国内用户请求至阿里云新加坡CDN,国外用户直接请求至Netlify CDN
  • 爬虫不会受到影响,经测速百度爬虫请求的还是Netlify CDN
  • 双站部署对SEO没有影响,阿里云CDN请求的Netlify源站网址没有公开,不会被爬虫爬取到;
  • HTTPS加速(通过阿里云CDN配置)。

如果你所在的地区访问速度特别慢的话,可以留言告知我。

更新时间: 19个月前 版本: 529067c0f