标签: serverless

  • 搬家记:从 Vercel 到 Cloudflare(Nuxt 项目x2)

    搬家记:从 Vercel 到 Cloudflare(Nuxt 项目x2)

    月底的时候,收到 Vercel 的邮件,提示我账号内有一些额度用量已经消耗 50%。我没在意,心想反正月底,马上不就归零了么?第二天起来越想越不对,我的 Vercel 是付费的 Pro 账号,计费周期是上月 22 日到本月 22 日,这才月底,才一周多,怎么会就用掉 50%?

    于是我回想起之前收到 Vercel 的邮件,说以后我每个月的费用会上升 30+美金,不由得背后一凛。赶紧上 Vercel 后台查看,发现 Vercel 开始用新的计费单位:Function Invocations。且 4 月 25 日起,新开通 Pro 的用户会使用这个方式计费;而 5 月 25 日(即上月底),我们这些老 Pro 用户也会采用这个方式计价。

    很明显,新计价单位比老的方式严苛很多,以至于我之前一半都用不掉的套餐费用,现在连半个月都撑不住。公平一点来说,我的项目都是 Nuxt,要走 Serverless Function,所以消耗可能比 Next.js 走 Edge Function 要高。但是,无论如何,这个价位都让我们动起了搬家的念头。目标毫无疑问,就是 Cloudflare。

    具体额度可能随时有变化,我就不在这里贴数字了,简单给大家划个标准:我在 Vercel 每月 $20 的额度,大约对齐 Cloudflare 的免费版;Cloudflare 每月 $5 的套餐额度,足够我 $50 Vercel + $5 Upstash,还有一大堆我没用起来的服务。

    单纯算经济帐,肯定是 Cloudflare 划算得多。但是 Vercel 行走江湖,靠的就是一手优秀的 DX,尤其在我搬家折腾完之后,更是这么觉得。整体过还比较顺利,但是坑也真没躲过去。接下来分享一些踩坑经历,希望对大家有帮助。

    第一步,创建项目。在 Cloudflare Pages 导入 Git 仓库即可,操作跟 Vercel 基本一致,无需详述。接下来,我们就有了部署在 xxx.pages.dev 子域名的网站,建议测试充分之后再切换域名。

    第二步,解决各种 [unenv] 问题。这个问题是由于 Cloudflare Worker 运行时精简(删掉)了一些 Node.js API 导致的。可能发生在各个环节,从部署到执行都有可能。我遇到的问题主要是:

    1. ioredis。因为我使用 Upstash Redis,所以直接换 @upstash/redis/cloudflare 然后使用 http endpoint 即可解决。两者的 API 有些许区别,不过功能性差异不大,替换起来不麻烦。
    2. Nitro Stroage。其实跟上面是一个问题,只不过表现不太一样。如果通过 nuxt.config.js 配置 Storage 使用 Redis,那么部署那一关都过不去……
    3. crypto.createHash。这个暂时没找到好办法,主要是 TiDB Serverless 最初使用 Digest 认证,所以我才必须使用。现在他们支持 Basic Auth 认证,所以我直接去掉对这个 API 的依赖就好了。

    第三步,安排 Cron job。这一步目前我也还没做好。Cloudflare Pages 不支持 Cron job,只能在 Workers 里安排 Cron Trigger。所以比较合理的做法是,建立一个统一的 cron worker,定时运行,粒度控制在比较合理的范围内,然后通过这个 worker 去调用分散在各个项目中的 cron job。

    于是,由于我们暂时无法离开 Vercel 的 Cron job,所以我们就还不能关掉 Vercel 上的项目。那么我们就必须开一个分支出来进行开发。好在 Cloudflare 可以支持指定特定分支作为 Production 的做法,所以这方面也没有问题。

    哦,对了,Pages 不支持在 wrangler.toml 里定义环境变量,以及我们在 Pages 里修改环境变量也不会触发重新部署,这点和 Worker 不一样,需要注意。

    最后,就是改变域名指向。我们必须在 Workers & Pages > 刚才的项目 > Custom Domains 配置自定义域名,仅在在 Websites > CDN 里配置是不够的,请大家注意。另外,由于 Nuxt 是 SSR 框架,所以我们必须关闭位于 Speed > Optimization > Content Optimization 的 “Auto Minify”,否则,可能会遇到重复的页面内容。

    还有一点,与 Vercel 不同,Cloudflare Pages 只包含 Edge 网络,并没有前面的 CDN 层。所以在 Cloudflare Pages 里增加缓存必须通过 Cloudflare CDN 来进行,同时 CDN 必须开启 Proxied,否则,原本在 Vercel 有效的缓存头就只能在浏览器里工作了。

    以及,Cloudflare Pages 没有提供页面重定向等功能,所以原本放在 Vercel.json 里的一些东西可能就要我们自己实现了。

    总结

    按惯例来总结一下。Cloudflare 的套餐性价比非常高,同样用量,价格可能 Vercel 的 1/10,还能覆盖其它服务。所以值得一试。但是问题也不少,比如运行时被进一步缩减、不支持 Cron job、没有 CDN 层、没有更高层级的 Headers 控制,等等,所以在使用时,体验可能还是略逊于 Vercel。尤其是迁移搬家,更要注意。

    好了,如果你对全栈开发,网站基础设施感兴趣,有问题有疑问,欢迎留言讨论。

  • 记一次 TiDB Cloud Serverless 超额导致的博客超时故障

    记一次 TiDB Cloud Serverless 超额导致的博客超时故障

    今天早上起来,习惯性地刷新博客统计页面,发现 502。这可不妙,好不容易我坚持到现在终于有点流量,于是赶紧想办法修复。

    博客基础架构

    我的博客架构大体是:

    • 小主机,本地跑 php8.2-fpm 和 nginx
    • 使用 nginx 代理提供服务
    • 数据库使用 TiDB Cloud Serverless
    • 外面套上腾讯云 CDN

    仔细一看,错误页面的 Nginx 是 1.18.0,正是我服务器上的版本,貌似是本地上游 php-fpm 的问题,不是腾讯云 CDN 的问题。ssh 登录服务器,基本正常,验证了判断。查看错误日志,tail /var/log/nginx/blog-error.log,大量的 upstream 错误。top 查看进程负载,服务器本身很闲,但是 5 个 php-fpm 进程虽然不忙,但是都跑了很久。

    重启治百病,先升级系统

    以前没见过这种情况,本着遇事不决先重启的思路,我想先升级重启试试。于是 apt update & apt upgrade 升级系统,接着 reboot。停了一会儿打开网页还是不行。

    登录服务器 service --status-all 查看服务,貌似都正常。查看博客服务器的配置文件,也没写错。输入 service nginx restartservice php8.2-fpm restart 重启服务,还是不行。

    然后 Google PHP8.2、php-fpm、502 等关键词,限制最近一周,看看会不会是新版本引入了新 bug。没有找到结果,应该也不是。

    会不会是 TiDB Cloud 没钱了?

    看过前面博客:💪 WordPress 使用 TiDB Cloud 替换 MySQL 💪 的同学可能知道,我不久前把博客从本地 MySQL 迁移到了 TiDB Cloud Serverless。会不会是欠费停机了?我觉得不应该呀,免费额度 5GB,我的博客数据库前几天看过才区区 300+MB,不会突然就突破限制。

    不过我还是打开了 TiDB Cloud,姑且看一眼吧。没成想,果然是 TiDB Cloud 额度用完了,不过不是容量问题,而是 RU(Request Units,请求单位,TiDB 的某个计费单位)超限。TiDB Serverless Tier 每个月有 50M 的免费 RU 额度,我当时已经用掉 59.6M,所以被停止服务了。

    不过这里有个问题:我的 php-fpm 整个被卡死了,因为 TiDB Cloud 没有及时断开连接,导致我的 PHP 一直在等待数据库响应,但实际上数据库是不会响应的,相当于我的 PHP 线程都在守活寡。直到超时,才得到解脱。这样一来,我的服务器也无法响应任何其它 PHP 请求,包括 phpinfo() 等未使用 TiDB Cloud,甚至那些只有简单 PHP 功能的请求。

    按理说我超额,他们应该拒绝连接,让我看到数据库连接失败的错误,而不是卡住我直到超时。这样一来,

    1. 至少我的服务器还可以响应别的 PHP 请求
    2. 有了数据库连接失败的错误提示,我也能尽快找到问题根源。

    上调预算

    TiDB 还是蛮大方的,不需要预付款、预充值,只要将来按用量结账即可。于是我把预算上调到 $5/月,然后,重启了服务器。结果,又发生了第二个意外。

    我以为上调预算之后,连接、请求就能恢复,结果没有,还是白屏。而且,从 TiDB Cloud 的统计页面来看,在上调预算之后,数据库经历了一大波密集的请求:

    直到约 30 分钟之后,我的博客才渐渐缓过来,我也才有机会写这篇复盘文章。

    我不太确定这波请求是哪里产生的,是我的博客还是 TiDB 的网关,这个有待进一步研究学习。

    请教 TiDB 大佬

    我带着问题在推上请教了大 V 能哥。他告诉我,按照目前的产品策略,超额用户也可以以很低的频率访问数据库,因为有人是占了太多空间,需要有机会让他删数据。

    那这就是彼之蜜糖,吾之砒霜了。我的情况是存储量少(不到400mB),但是请求数高(我看的时候为 60M),所以除非调高预算,我不存在继续使用的可能性。但是他们又不会拒绝我的服务,于是就变成了我服务器上的 php-fpm 被卡死在连接数据库阶段,无法响应任何 PHP 请求。

    我把这个问题反馈给了 TiDB 的社区工作人员,期待他们能解决这个问题。

    下一步:解决方案

    这次故障的修复过程对我来说还是挺新鲜的,也还算顺利。给我在系统设计领域提供了新的经验,所以我拿出来分享给大家。

    不过话说回来,从白嫖的角度来看,迁移到 TiDB Cloud Serverless Tier 上似乎不是很明智。按照 WordPress Jetpack 的统计,我现在每月访问量大约是 7k UV,10k PV,如果这个级别就要花钱,而且动辄几刀的话,那我可能还是迁回去用本地数据库好一些。

    当然,解决方案还是有的。

    首先,Serverless Tier 可以创建多个节点,每个账号的最初的 5 个节点都有 5GB 空间+50M RUs/M 的免费用量。所以我可以写一个自动化脚本,每周将数据同步到下一个节点,然后自动修改链接类到新的节点。嘿嘿嘿,不知道这样的作品能不能参加 Hackathon 😂😂

    其次,好好查查 slow sql,找找优化点。减少每次请求产生的 RU 消耗。

    再次,升级 CDN 配置。我目前的网页都是 30d 缓存,按理说不应该有很多消耗才对。后台只有我一个人在用,不应该有很多数据库访问。我怀疑还是这块儿没搞好。应该有不小的优化空间。

    总结

    TiDB 正在举办新一年的 Hackathon,我也厚着脸皮去要了 $100 的赞助,白嫖大业应该还能再坚持一段时间。如果你也对数据库应用开发感兴趣,我强烈推荐你也来参加这次 Hackathon:【TiDB Future App Hackathon 2023 】TiDB 首届全球黑客马拉松,开发者的狂欢夏日盛会!快来一起 Coding 吧!这次 Hackathon 针对应用层,基本上使用 TiDB Cloud Serverless 就可以,适合各个领域的开发者参加。

    无论如何,感谢 TiDB 提供给我们免费、好用的数据库产品,也推荐大家使用 TiDB Cloud Serverless。如果大家有什么意见建议,欢迎留言讨论。

  • 聊聊 Serverless 与 Edge Function

    聊聊 Serverless 与 Edge Function

    熟悉我的同学可能记得,前几年我经常推荐 Serverless,而且我的博客里现在还挂着 LeanCloud 的推荐链接。我觉得 Serverless 对前端、全栈开发者来说简直是个福音,很多原本很难的开发工作,有了 Serverless 之后,都能很容易的由前端处理,大大扩展了前端的能力覆盖范围。

    时至今日,我们不仅有 Serverless,还有 Edge Function,后者几乎没有冷启动的问题,更能提供 SSR 功能,好上加好。很多数据存储服务也针对性地提供好用的接口。今天的开发环境对前端来说,简直无与伦比。所以我想聊聊这个话题,希望每个前端都能在 Serverless/Edge Function 得帮助下成长为全栈开发。

    Serverless 是什么?

    我就不去抄准确定义了,按照我的体验来分享:

    1. 不需要维护独立的服务器
    2. 分为两个部分:
      1. 基于行级权限控制的数据库
      2. 可以自动扩容、降容的云函数执行器
    3. 云数据库,配合行级权限,配合合理的数据逻辑,可以在前端完成大部分数据处理的工作
    4. 云函数可以自动扩容、降容,可以休眠、启动,可以完成云数据库无法放在前端的操作
    5. 云函数以函数为一个执行单位,实现更精准的资源控制

    总之,前端有了 Serverless,就可以在没有后端、没有运维的配合下,独立完成完整应用的开发,并且具备相当强的扩展能力,费用也很低。

    其它应用场景

    除此之外,Serverless 还可以用在各种有突发计算高峰的场景里,比如音视频处理。我们可以利用 Serverless 在没人使用时自动休眠(不计费),有人访问时自动启动的特性,有需求的时候才启动,完成计算后自动关机,既节省成本,又提供很高的理论并发。

    Serverless 的问题

    早期的 Serverless 调度系统有些问题。出于学习成本的考虑,早期 Serverless 多数是基于容器技术,虽然可以完整支持大部分编程语言及其 API,但是冷启动一般都需要不少时间,少则十几秒,多则几十秒。

    这么久的启动时间,对于计算密集型领域来说,问题并不严重。因为在这些场景里,几十秒的启动时间占比不高,通常来说用户需要等待的时间远比它久,自然有队列和轮询放在前面。但是对于一般的网站应用,服务普通客户,如果启动一次要几十秒,那就很难接受了。

    比如最近大热的 ChatGPT,有些同行尝试用 Serverless 做转发,就受困于冷启动,经常超时报错。

    一代更比一代强:Edge Function

    我不太确定 Edge Function 是什么时候诞生的,最初我以为 Edge Function 无非就是跑在运算力富裕的边缘节点上,本质上跟 Serverless 没什么区别,直到前些日子开始大规模使用 Vercel,深入了解之后,才明白 Edge Function 的优势。

    简单来说,无论是 Vercel、Supabase、还是 Cloudflare Worker,都抛弃了以前基于 Docker 的做法,或者精简运行时,或者使用 deno 这样更快更小的核心,将冷启动的速度降到毫秒级——基本就是网络传输的延迟级别。

    于是 Edge Function 的可用性就大大提升,可以用在各种速度敏感型的场合,比如现代框架的 SSR、代理服务器、HTML 内容改写,等等。

    目前,我的 Edge Function 主要用在以下几个场景:

    1. Nuxt.js/Next.js 的 SSR
    2. 代理 OpenAI 的 API 访问
    3. 操作 Upstash Redis 存储和修改数据
    4. 响应 Stripe 的付款请求

    Vercel Edge Function 的限制

    我用 Vercel 比较多,这里介绍一下 Vercel Edge Function 的限制。

    首先,Vercel Edge Function 是 node.js 的子集。除了拥有完全一致的语法和基本对象之外,Edge Function 并不能使用全部的系统 API,比如 fs、http/https 等。所以类似 axios 这样知名的 ajax 封装就不能使用;也不能使用 OpenAI 的官方 npm 包。

    Edge Function 只支持 ESM,所以依赖里面的包即使没有用到系统 API,也必须使用 ESM 才能使用。所以我们必须经常性的处理一下公共包。

    虽然支持 TypeScript,但部署的时候,会使用 ESM 编译,所以 import 必须使用相对路径,否则会报错。报错的内容是使用了不支持的格式,非常有误导性。

    其它就是一些系统性要求,比如代码限制、内存限制、请求体限制等,我目前都还没有撞到。大家小心点就是。比较可能遇到的问题是,Edge Function 30s 内必须开始返回内容,这在 OpenAI 开发中很容易遇到问题,开启 stream: true 就好。

    更好的生态环境

    Vercel、CloudFlare 均提供非常完整的网络环境,包括网站、CDN 缓存层等必备服务。

    如果要使用数据库,选项非常丰富,除了 Vercel 自带的各种不解渴的“小样”,我们还可以使用 Upstash Redis,MongoDB,PlantScale MySQL,Supabase PosgreSQL,以及 TiDB Cloud Serverless。

    基本上,应有尽有,几乎所有 Web 开发所需要的存储方案都能找到有免费额度的试用装。开发环境真是盛世空前。

    我们应该怎么做

    现在经济大环境不好,很多同学面临失业、降薪,V2EX 上经常有同学讨论是开网约车好还是送外卖好……这个我也没办法。但是从另一个角度来说,我们的开发环境却是史无前例的好,部署、运维成本非常低,几乎所有必须的服务都有免费试用,每家都提供清晰的文档、易用的 SDK。

    我建议,大家好好利用闲暇时间,利用现在各种生成式模型大爆发,但是市场还没稳定下来的时间节点,多多尝试,即使做不出惊世之作,也能为自己的将来累积足够多的资本,坚持到云开日出那一天。

    广告时间:我的全栈开发课程

    发现忘记打广告了,赶紧补上。

    我目前正在连载一套云原生全栈开发课程,使用 Nuxt3 + Vercel + Serverless 数据库开发。目前发布了三集,本周计划制作第四集(如果有时间就做第五集,嗯嗯),请大家观看,有号的话还请帮我一键三连,多谢。

    B站地址:Nuxt3+Vercel+Serverless 数据库全栈开发

    油管地址:Nuxt3+Vercel+Serverless数据库全栈开发 – YouTube

    总结

    曾经面试金山的时候,有位面试官问我:你这么大年纪,你觉得你比年轻人有什么优势?我答道:因为我年纪足够大,见识过足够多的技术发展,所以我能更快地学会一门技术,也能更准确的判断一门技术是否值得学习。我一直很看好 Serverless,如今有了 Edge Function,serverless 更好用;有了各种服务,serverless 更强大。Serverless 是未来全栈不可或缺的技术。

    希望大家都学会使用。有任何问题、建议、意见,欢迎留言讨论。

  • 【视频】Nuxt3+Vercel+Serverless 全栈开发(1):技术选型介绍,项目基础搭建

    【视频】Nuxt3+Vercel+Serverless 全栈开发(1):技术选型介绍,项目基础搭建

    大家好,时隔小半年,我又来做系列视频了。这次计划结合近期的一些开发经验,分享最近我比较喜欢的全栈+高效+免费+云原生技术方案。

    这套技术方案大约是这样:

    • Nuxt3
      • 提供 Vue 开发环境
      • 提供服务器渲染 SSR 能力
      • 提供 API 环境
    • Vercel
      • 提供部署环境和各项网站能力
      • 提供 Edge Function 和各种存储
      • 提供全球化服务能力
      • 提供 SSL
      • 免费额度足够用很久
    • Upstash
      • 提供 Redis
      • 免费额度足够用很久
      • 付费也不贵
    • TiDB Cloud Serverless
      • 云数据库,MySQL 兼容 API
      • HTTP endpoint
      • 免费额度足够用很久
    • 其它
      • Nuxt- i18n
      • TailwindCSS
      • DaisyUI
      • GitHub
      • pnpm

    使用这套技术方案,可以应对绝大多数网站需求,部署在全球化网络里,使用丰富的免费资源。云原生会带来天生的高可用性、鲁棒性、伸缩性。

    这是第一次分享,详细介绍了这套技术选型,nuxt3 项目的基础搭建,和它自带的路由、服务器 API 系统。

    这次会把每次的分享压缩到 25~30 分钟,降低观看门槛。

    如果你有任何问题、建议,欢迎留言讨论。请 b 站有号的同学帮忙分享完播一键三连,谢谢大家。

    另外,我也在 YouTube 上上传了一份,大家有空的话,麻烦帮忙关注下我的油管频道,感谢感谢。肉山全栈小课堂 – YouTube