我在周末独自完成了 Doorbell 这个项目,用来参加 WeMakeDevs × Zerops 挑战赛。文章结尾有在线网关可以亲手测试,也有一节专门写它不能做什么。 事情要从一次 GitHub 集成测试说起。当时我开着一条隧道,准备接收 GitHub 的 push 事件。我合上笔记本去买咖啡,回来以后发现推送事件不见了。不是延迟,不是排队等待,就是消失了。 我第一反应是自己配置错了。但查了 GitHub 官方文档,文档写得很清楚:“GitHub does not automatically redeliver failed deliveries.” 一次投递失败,就轮到你自己解决——除非打开网页界面,手动重新投递。 我又去看了其他服务商,以为 GitHub 是特殊情况。结果不是。再看一遍这句话:Shopify 不只是放弃这次事件,而是直接退订你的应用。这意味着失败的代价不是少一条消息,而是整条通道都可能被关掉。 关于隧道,有个没人提前告诉你的部分:隧道把你的笔记本电脑变成了别人系统里的生产基础设施。发送方不会等你。顾客凌晨两点结账;CI 在你出门吃午饭之后跑完;你在火车上 WiFi 断了三十秒。这些瞬间,发送方只会收到一个 502。它消耗掉本来就少得可怜的三四次重试机会中的一次,然后事件就彻底消失了。 这时候会有人说:ngrok 不是已经有 replay 功能了吗?有,而且很好用。但 ngrok 只能重放它已经看到的请求,也就是说,事件到达那一刻,你的隧道必须是连着的。真正致命的,永远是那些你不在线时到达的事件。这是结构性问题,不是缺个功能:隧道是管子,不是信箱。你这一端没人听,请求就没有地方可去。 所以我做了个信箱,给它取名 Doorbell。本质上它是一条隧道,但在路径上加了一个数据库。事件到达时,即使你不在线,也会先存下来;等你连上,再按门铃通知你。 现在你就可以亲手毁掉它。我跑了一个公共网关,也就是那个永远在线、负责维持隧道的服务器。上面有一条叫 shop 的隧道,当前没有任何东西连着它——状态和你合上盖子的笔记本一样。你可以去发一个事件,看看它是怎么被接住、又怎么在你回来之后被递送的。 最后说它不能做什么:它不能保证上游一定会重试,不能替你做消息格式转换,也不能在你断电时保证数据库本身仍然在线。它只解决一个核心问题:让隧道从一个被动的管道,变成一个不会随手丢弃来件的地方。

打开网易新闻 查看精彩图片