为什么我们将开源😼inboxkitten(7700 万个无服务器请求)从🔥Firebase 迁移到☁️Cloudflare workers & 🐑CommonsHost
立即获取邮件!📩
好的,猫咪团队,我们需要一个计划来保护夏季促销!💳
使用
猫Cloudflare 工作人员☁️
但是,也存在一些问题……
总结一下划痕...
这很酷,但是我为什么还需要 Inboxkitten 一次性电子邮件呢?
嘿,31 美元的 Firebase 静态文件托管怎么样?
下一步是什么?
发货愉快🖖🏼🚀
立即获取邮件!📩
自从我们最初推出inboxkitten.com以来,这是一个用于创建一次性电子邮件服务的免费开源无服务器项目......


The Stack:在 14 小时内制作一个免费的开源一次性电子邮件服务(inboxkitten.com)😼
Eugene Cheah 为 Uilicious 撰稿 ・ 2018 年 9 月 22 日
🐈小猫繁殖过多,已经失控了……
- 产品搜索排名第三
- 二月份账单冲击:143 美元
- 221 GB 静态网站数据(来自 cloudflare 缓存未命中)
- 215 GB 的电子邮件数据
- 7700 万个 API 请求
- 20,000+ 独立访客(根据 cloudflare 的数据)
- 我的 Steam 夏季促销资金耗尽了 😭(那 143 美元肯定是从某个地方来的)

好的,猫咪团队,我们需要一个计划来保护夏季促销!💳
现有 AWS lambda 或 GCP/Firebase 云功能的主要限制之一是它在任何时间点将 1 个请求限制为一个应用程序实例。
虽然这很棒,但如果您正在压缩图像或执行复杂的事情。
Inboxkitten API 的唯一作用是使用 API 密钥向保存实际电子邮件的 mailgun 发出 HTTP 请求,并返回结果。
因此,我们的资源消耗远低于 CPU 的 1%,或者每个请求占用的内存不到 10MB。也就是说,低于每个请求占用 128MB 内存和专用 CPU 的最低要求。
因此,我们最初的计划是,一旦这些小猫在非常恒定的负载下长大,就将其扔到每月 5 美元的 Linode Nanode 1GB 实例上。
然而,它的缺点是,在峰值负载下,或者当请求量达到每月海量请求(超过一个实例的负载)时,它无法自动“扩展”。(当然,我们并不需要支持这样的负载)
因此,本着无服务器乐趣的精神(这使得该项目很受欢迎),我们将该选项放在一边并询问......
如果有一个无服务器平台,并且采用另一种计费模式,会怎么样?如果它只按请求计费,或者只按使用的 CPU 和内存量计费,会怎么样?如果我们……
使用
猫Cloudflare 工作人员☁️
Cloudflare Worker 是日益流行的“边缘”无服务器计算的一部分。它还能将无服务器计费简化为单一指标。
将之前复杂且难以解读的 GCP 账单转变成......
计费项目 | 用法 | 单元 | 总成本 | 平均价格(每百万次调用) |
---|---|---|---|---|
调用 | 77,418,914 | 调用 | 30.17 美元 | 0.390 美元 |
CPU 时间 | 4,677,797 | GHZ-秒 | 44.78 美元 | 0.578 美元 |
出口 | 215.12 | 吉比字节 | 25.21 美元 | 0.326 美元 |
记忆时间 | 2,923,623 | 吉比字节秒 | 6.31 美元 | 0.082 美元 |
日志卷 | 61.16 | 吉比字节 | 5.58 美元 | 0.072 美元 |
全部的: | 112.05 美元 | 1.447 美元 |
变成更容易理解的东西,并且每个请求总体上更便宜......
计费项目 | 用法 | 单元 | 总成本 | 平均价格(每百万次调用) |
---|---|---|---|---|
调用 | 77,418,914 | 调用 | 39美元 | 0.5 美元 |
全部的: | 39美元 | 0.5 美元 |
😸 这笔净节省足够在夏季促销期间购买另外 7 款售价 9.99 美元的游戏!
并且具有较低延迟边缘计算的额外好处!
但是,也存在一些问题……
1)<5ms CPU时间限制
每个请求的 CPU 时间限制为 < 5ms,这与请求时间(也称为挂钟时间)有很大不同,因为它仅计算 CPU 在我们的功能本身上花费的时间,而忽略其所有睡眠/等待时间。
这与 GCP 或 AWS 测量函数从启动到结束所花费的时间(包括所有睡眠/等待时间)的方式相反。
在这样的设置下,像折叠 DNA 链或猫图像这样的无服务器函数会消耗大量的 CPU 或 RAM,导致 Cloudflare 无法使用。
然而,我们的无服务器函数 99.99% 的时间都在等待 mailgun API 响应。因此,<5ms 的限制非常完美。
此外,如果我们需要将其升级到<10ms,它是一个可选的插件。
2)与 express.js 不兼容(因为它使用 Web Worker 模式)
另外需要注意的是,Cloudflare 工作者基于Web 工作者模型,它像拦截器函数一样挂接到 Cloudflare 中的“fetch”事件上。
因此,在 express JS 中不要使用以下内容(就像我们目前对 firebase 所做的那样)
const express = require('express')
const app = express()
app.get('/', (req, res) => res.send('Hello World!'))
const port = 3000
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
在 Cloudflare 中,它将是以下内容
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request))
})
async function fetchAndApply(request) {
return new Response('hello world')
}
因为这会对代码结构造成巨大的根本性改变。对于大型现有项目来说,这可能是一个重大的障碍,因为涉及大量的重写工作。尽管两者极其相似。
也许有一天有人会想出一个 Cloudflare 到 express.js 适配器?
但对于我们来说,由于项目比较简单,这只是一次简单的重写。您可以在这里比较 express js 版本和github 上的Cloudflare 版本之间的代码差异。
虽然 workers 是一个开放标准,Cloudflare 是唯一的主要提供商,但它目前也是一种供应商锁定形式。
3)每个域名限制一个脚本(除非您在企业中)
虽然这对 inboxkitten 来说不是什么大问题,但对许多商业/生产工作量来说却是一个大问题。
因为 Cloudflare 无服务器包不能分解为针对单个子域和/或 URI 路由的更小的包。
这使得事情变得非常复杂,在许多更复杂的设置中,不可能在单个域上分离测试和生产代码。
然而在我们的用例中,因为这是一个业余项目......这并不重要......
总结一下划痕...
- <5ms CPU时间限制
- 与 express.js 不兼容
- 每个域限制一个脚本
只需要由@jmtiong快速重写一天,我们就完成了。
这很酷,但是我为什么还需要 Inboxkitten 一次性电子邮件呢?
当前的关键用例之一,也是我们构建此项目的原因,是将电子邮件验证作为自动化测试脚本的一部分。例如:
// Lets goto inbox kitten
I.goTo("https://inboxkitten.com");
I.see("Open-Source Disposable Email");
// Go to a random inbox inbox
I.fill("email", SAMPLE.id(22));
I.click("Get Mail Nyow!");
// Check that its empty
I.see("There for no messages for this kitten :(");
// Testing for regular email
// (sent using a jenkins perodic build)
I.goTo("https://inboxkitten.com");
I.see("Open-Source Disposable Email");
I.fill("email", "ik-reciever-f7s1g28");
I.click("Get Mail Nyow!");
// See an email we expect, nyow
I.see("Testing inboxkitten subject");
具有可共享的测试结果,例如

此外,它简单、酷炫,而且摆弄起来很有趣。
嘿,31 美元的 Firebase 静态文件托管怎么样?
最简单的免费解决方案是将整个网站放到GitHub 页面上
然而本着开源精神......
我们要向来自🐑 commonshost.com的朋友们致敬,这是一个由新加坡🇸🇬 构建的开源静态网站托管平台
并帮助他们在全球网络上的 22 多台服务器上进行真实的生产工作负载测试,以推动他们的网络发展。
至于为什么选择 commons host 而不是 GitHub... 因为它很酷,而且我想支持 CDN 世界的弱势群体,成为测试世界的弱势群体。
哎呀,我说的是失败者吗?我是说失败者😼
下一步是什么?
由于该项目相当独特的简洁性(可快速重写)以及繁重的生产负载,我正在考虑将其部署选项扩展到尽可能多的无服务器选项,甚至基于 Docker 的部署。
探索与实际全天候生产负荷之间的各种权衡。
完毕
- GCP/Firebase:功能和托管
- Cloudflare 工作人员
- Commonshost 主机托管
待办事项
- Docker 容器部署
- ECS Fargate
- 数字海洋 Kubernetes
- AWS lambda
- 其他的??
让我们看看这艘猫船接下来会驶向何方……在那之前,我们将小憩一会儿