2

Vercel, Cloudflare, fly.io 我的云服务三剑客

 1 year ago
source link: https://limboy.me/posts/vercel-cf-fly/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Update: 在排查 Cloudflare 缓存命中率低的问题时,发现没有一台 Server 实在是不方便。比如想看下哪些请求透过了 CF,直接到了源站,如果内容 deploy 在 Vercel 上,就看不到这些请求日志。所以虽然 Vercel 很方便,用起来也很舒服,但一些能力上的缺失在某些场景下还是挺难受的,因此还是转向了 VPS(Vultr) + Cloudflare 的传统配搭。

自己时不时地会写一些网页(如 拼音猜成语)或部署一些静态页面(如这个博客),或者托管一些资源文件(如播客音频),这就涉及到线上服务的选择。目前来看 Vercel, Cloudflarefly.io 能较好地满足我的大部分需求。

DNS 管理 & CDN

这部分交由 Cloudflare(简称 CF) 来管理。在 CF 后台新建 Site 后,在域名注册商处,将 Name Server 设置为 Cloudflare 的 Name Server 就行了,就是下面这两个

leah.ns.cloudflare.com
wesley.ns.cloudflare.com

CF 也提供域名注册服务,如果是新的域名,可以直接在 CF 注册,管理起来更方便,价格也不贵。

因为 CF 的主营业务还是 CDN,所以提供了一个很方便的功能:代理网站静态资源,也就是这朵橘色的云(Proxy Status)。

cf-dns.jpg

开启了之后,domain 下的资源(如图片,CSS 等)会被 CF 缓存到 CDN,用户访问这些资源时,就直接访问 CDN 上的缓存,不会到自己的服务器,可以节省很多流量。而且 CF 的 CDN 流量是免费的,所以不用担心哪天站点访问量剧增带来的流量费用。

PS: 开启「自动代理」后,如果出现直接访问 OK,但通过 CF 访问就会出现问题的现象,可以把 SSL/TLS 设置为「灵活」。

cf-forwarding-settings.jpg

如果发现 CF 访问统计中,有很多的流量没有缓存,可能是跟 Vercel 返回的 Cache-Control 有关,比如 Cache-Control: public, max-age=0, must-revalidate,表示不缓存,这样 CF 也要遵从这个约定,当用户访问资源文件时,如果浏览器本地没有缓存,或者已经过期,每次请求到了 CF 这里后,CF 也还是要到源站(Vercel)去取。这样不仅没有让 CF 发挥 CDN 的优势,反而因为要回源,导致请求变慢。

好在 Vercel 支持自定义 header 规则(更多的规则可以看这里),我们可以在 vercel.json 里重新定义 Cache-Control

{
  "headers": [
    {
      "source": "/(.*).(jpe?g|png|ico|webp|svg|mp4|gif|xml|ttf|woff2?)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    }
  ]
}

这样当访问特定后缀的资源文件时,就会返回我们定义的 Cache-Control,CF 会根据新的 Cache-Control 策略来缓存,比如这里设置了永不过期。

PS: Vercel 有个页面专门讨论了与 CF 并存的问题,想进一步了解的话,可以看一下。

PPS: 这么做确实可以达到效果,但 CF 后台显示缓存命中率只有不到 10%,需要进一步排查。

CF 默认不缓存 HTML 文件,如果要设置更加灵活的缓存策略,可以通过 Page Rules 来完成,免费用户可以设置 3 个规则,基本够用了。

cf-page-rules.jpg

还有一个好处是,可以在 CF 的后台看到页面的访问统计,虽然比较简单(能看到访问次数,但无法精确到页面,或者来源),但不需要额外的 JS 代码,不用依赖第三方访问统计服务,也还不错。

CF 还可以托管一些存储服务的文件,以 Backblaze(又称 B2) 为例,对 DNS 的 CNAME 做一下映射(同样要将 Proxy 设置为 Proxied),比如将 assets.example.com 映射到 f002.backblazeb2.com,通过后台或 API 上传资源文件(如播客的音频)后会得到 B2 的 URL,将域名换一下就行了。比如将 https://f002.backblazeb2.com/a/b.mp3 替换为 https://assets.example.com/a/b.mp3,就可以使用 CF 的 CDN 服务了。

通过 SSG(静态内容生成器)生成的博客或文档等静态资源,会部署到 Vercel 上,体验确实很不错。比如 Connect Github 后,做一些简单的配置,就能方便地 Deploy 了。push 到 main 之外的分支,可以生成 Preview 页面,确定内容正确后,再 push 到 main 分支,就上线了。这也是 Vercel 提倡的 Develop, Preview, Ship 流程。

每个月 100 G 的流量(所有 Projects 加起来)如果都走 Vercel,可能不太够,但结合 CF 就完全能 hold 住了(流量主要是一些 HTML 页面)。

如果要写一些复杂的页面或涉及到一些后端逻辑,也可以使用 Vercel 开源的 Next.js。API 会以 Serverless 的方式运行(所以不要依赖一些内存全局变量)。最近 Middleware 也 GA 了,可以在请求到达具体页面前再做一些处理(比如判断是否有特定的 Cookie,然后重定向到特定的页面)。

CF 也提供类似的服务 Cloudflare Pages,不过目前对 Vercel 还比较满意,就没考虑切换。

如果涉及到数据库,对个人项目来说,要么在单独的 VPS 上部署,要么在 Serverless code 里通过 API 去连接 Cloud Database Service,前者有一定的维护成本,要保障 VPS、后端服务、DB Service 的正常运行,还要考虑各种运维(网络耗时、磁盘空间、CPU、内存占用等等),后者就要找一个合适的服务商,确保价格、空间、流量、使用体验等比较满意。

其实也可以有第三种选择,我选的是 fly.io,可以简单地理解为把 Docker 部署到边缘节点,让用户可以就近访问服务。fly 的免费版本提供了一定的存储空间(3GB,先创建 Volume,然后 mount 到 App 上),一些简单的项目,一个 SQLite 文件就搞定了,备份起来也很方便。更 Serious 的项目可以使用他们提供的 Postgres 数据库(支持多节点部署,读写分离)。

这样就兼具了 VPS 的灵活性,又免去了不少运维成本,又因为服务可以部署在全球的各个节点,访问速度上也比较有保障(挂了 Volume 后,就只能锁定单个区域,因为 Volume 跟 App 和 Region 绑定)。

目前只是在上面部署了一个小项目,还没有较正经地使用,不过有 RemixKent 的背书,从一些其他的反馈来看也还可以,应该会是不错的选择。

还有一个原因是 fly.io 给我的感觉也是满酷的,比如 Rust 开发的招聘文,这是其中一段:

The premise of our hiring process is that we’re going to show you the kind of work we’re doing and then see if you enjoy actually doing it; “work-sample challenges”. Unlike a lot of places that assign “take-home problems”, our challenges are the backbone of our whole process; they’re not pre-screeners for an interview gauntlet.


这三家服务商基本覆盖了我所有的线上需求,而且只需支付很少(或者免费)的费用就能支撑足够大的访问量(Cloudflare 功不可没)。如果你也有类似的需求,或许可以考虑下。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK