
2026 年 9 月 24 日 18:42(UTC),我们将所有 Cliqer 实时连接从 Cloudflare Workers 和 Durable Objects 迁移到了我们自己的专用服务器上。我们尝试过边缘计算,而这一次,它让我们失望了。如果您正在使用 Cliqer,您的工作方式不会有任何变化。变化发生在底层:您的房间不会再因为无人能解释的原因而重启。
本文将坦诚地讲述其中的原因。这也是一封感谢信,因为我们仍然是 Cloudflare 的客户,也依然真心欣赏他们打造的产品。
- 在四个月里,每个 Cliqer 房间都运行在 Cloudflare Durable Objects 上。这个构想很美妙:每个房间都在边缘拥有一台属于自己的、始终在线的小型服务器。
- 实际上,Cliqer 的房间每天都会在底层被重启数次,既没有触及内存上限,也没有触及 CPU 上限,我们的代码没有报错,也没有任何部署。每次重启都会断开该房间内的所有连接。
- 我们构建了大约 18 种不同的机制,来向您隐藏这些重启。有些奏效了。但这种复杂性本身开始引发新的 bug。
- Cliqer 的实时服务现在运行在我们自己的专用服务器上,仍然位于 Cloudflare 的网络之后。没有意外重启,没有存储重置,也没有「位置抽签」。
- 速度也更快了:桌面应用的启动检查响应速度最高提升 17 倍,空闲连接的建立时间从 1.2 秒缩短到 0.14 秒。
- 如果现在连接断开,原因是明确的:您的网络、一次约一秒即可完成重连的计划更新,或者不可抗力。它不再是一个谜。
我们想要构建什么
Cliqer 是一款现场工具。演讲者轻点手机,一块可能远在另一个大洲的屏幕上的幻灯片随即翻页。连线嘉宾加入节目,主持人切换信号源,计时器在舞台上倒数。这一切都依赖 WebSocket:这种长连接绝不能有丝毫闪断,因为一旦闪断,就会发生在观众面前。
Durable Objects 看起来是完美之选。每个房间都拥有一个单线程对象,持有自己的套接字和存储,运行在 Cloudflare 的网络上。无需管理服务器,无需规划扩容。到 5 月下旬,所有房间都已运行在其上,旧版 Cliqer v1 桥接服务也在 6 月加入。
出了什么问题

无法解释的重启
Durable Object 随时可能被平台重启,而一旦重启,它持有的每个 WebSocket 都会被关闭。我们专门针对这一点检查了一个 24 小时窗口内的日志:没有一个套接字在重启后存活。 一个都没有。
如果重启很少发生,这也无妨。但事实并非如此:
- 位于里斯本、承载所有房间的那个对象在 5 天内重启了 21 次,其中 4 次发生在同一个小时内。没有内存溢出,没有触及 CPU 上限,只有少量平台内部错误,而我们也没有进行任何部署。
- 我们迁移了它。Durable Objects 会停留在首次创建的位置,因此迁移意味着重新创建它,并祈祷它落在更好的地方。第一次尝试落在了马德里,下一次落在了阿姆斯特丹。
- 在阿姆斯特丹,重启依然接连不断,每隔 2 到 16 小时一次,平均约每 8.7 小时一次。
- 到了 9 月,服务旧版房间的那个对象仍在无故每天重启 2 到 5 次。9 月 8 日 18:53,所有旧版连接在同一毫秒内全部关闭。我们没有部署,状态页面上也没有任何事故通报。
对您而言,每一次重启都意味着演示遥控器停止响应、连线嘉宾突然消失,或者应用在节目进行中提示正在重新连接。
超时并重置房间的存储
9 月 7 日至 10 日期间,我们在 4 个对象上共 8 次看到这条错误信息:“Durable Object storage operation exceeded timeout which caused object to be reset”。其中一次重连尝试等待了 44.5 秒才宣告失败。本应只需几毫秒的存储读取,却让整个房间随之瘫痪。
每次部署都会重启所有房间
这一点有文档说明,也合情合理:发布新版本的 Worker 会重启其 Durable Objects,而重启它们就会关闭其上的连接。8 月 19 日至 21 日期间,在线客户房间中 44% 的重连是成批同步发生的,而我们自己在一天内的三次发布导致所有房间断开,其中一次正值节目进行中。
于是我们将套接字拆分到独立的 Worker 中,并构建了一个工具,检查每个改动的文件,判断哪些部署允许触及房间。这个办法奏效了:下一次网站发布时,有五位主持人在线,房间事件为零。但这也意味着,任何对实时代码的改动仍会重启所有人的连接。
在现场节目中坑了我们的微妙行为
- 长达 16 分钟的静默。 8 月 4 日,43 个套接字保持连接,但没有任何消息被投递到任何房间。边缘一直在代替房间响应心跳,因此没有客户端察觉到异常,也没有人重新连接。这源于我们刚刚启用的一项平台功能,再加上我们自己的状态记录逻辑。我们在同一周内就回退了这项改动。
- 幽灵主持人。 关闭事件并不保证能送达处于休眠状态的对象,因此一位早已离开的主持人可能在数小时内看起来仍然在线。
- 一个被缓存卡住四小时的 URL。 8 月,我们 Worker 前面的一层缓存卡在了桌面应用启动时检查的那个 URL 上。应用无法启动。而同一个 URL 加上一个无意义的参数,一秒内就能得到响应。
我们为应对而构建的东西
在这四个月里,我们构建了大约 18 种独立机制来向您屏蔽平台问题:更快的心跳、清理幽灵主持人的扫描、每次唤醒时从存储中重建的注册表、在重启后依然保留的身份标识(以便您的应用能够恢复会话)、独立的套接字 Worker、覆盖 161 个文件的部署分类器、重新抽取部署位置、中继看门狗、按房间分片,以及与之配套的跨分片席位账本。
其中三项后来被我们删除了,因为它们带来的麻烦比解决的问题还多。而且每一个变通方案都增加了更多活动部件。将房间分片到多个对象之后,我们遇到了一个替错误分片作答的失控房间、一个陷入迁移循环的观众,以及一个可以跨分片绕过的席位上限。每个问题都得到了修复,但我们把时间花在了绕开平台的工程上,而不是打造 Cliqer。
公平地说
那几个月里,并非每一次连接断开都是 Cloudflare 的问题。我们核查过:
- 86% 的单次重连是单台设备因自身网络而断开:企业代理、场馆 Wi-Fi、排斥长连接的防火墙。这也是我们在 8 月为桌面应用推出企业网络支持的原因。
- 有些成批断连是我们自己的部署造成的,还有几次是我们自己的调试工具引起的。
- 我们从未就这些重启提交过支持工单。这是我们的责任。
Durable Objects 是一项出色的工程成果,对许多工作负载来说,它恰恰是正确的选择。而一个面对现场观众、绝不能闪断的房间,对于一个可以随时重启它的平台而言,恰好是最坏的情况。我们尝试将边缘用于实时服务,而这一次,它让我们失望了。这是对这类工作负载的结论,而非对边缘计算本身的评判。
现在由什么承载您的房间

Cliqer 的实时服务现在运行在我们自己的专用服务器上。它们负责网站、API 和所有 WebSocket,直接承载每个房间,并以本地数据库作为支撑。流量仍然经过 Cloudflare 的网络,因此您依然享有同样的防护和同样的地址。
消失的问题:
- 不再有来自底层的重启。进程会一直运行,直到我们决定停止。
- 不再有位置抽签,也不再有存储超时导致房间重置。
- 不再分片。一个房间,一个位置,一个唯一可信的数据源。
我们坦诚说明的事项:
- 当我们发布更新时,您的连接会重连一次。 新版本会在旧版本旁边启动,并几乎瞬间接管。您的应用会在约一秒内以相同的身份重新连接,并从原来的状态继续运行。在我们的演练中,4,757 个网页请求经历了切换,无一失败。
- 我们的服务器位于欧洲。我们宁愿运行自己完全理解的机器,也不愿依赖数百个无法洞察其内部的地点。
速度也更快了
我们会在自己这边记录每个 API 请求的耗时,因此可以用真实流量而非实验室测试,对比迁移前一周与迁移后几天的数据。
17x
桌面界面检查提速
10x
版本检查提速
0.14 s
即可建立空闲连接,此前为 1.2 s
4x
团队仪表板统计提速
| 应用正在执行的操作 | 之前(中位数) | 之后(中位数) | 提速倍数 |
|---|---|---|---|
| 桌面应用检查界面更新 | 178 ms | 10 ms | 17x |
| 桌面应用检查新版本 | 344 ms | 32 ms | 10x |
| 获取视频中继凭据 | 210 ms | 56 ms | 3.8x |
| 加载您团队的仪表板统计数据 | 973 ms | 240 ms | 4x |
| 检查您的许可证和套餐 | 268 ms | 119 ms | 2.3x |
最慢的请求改善得更加明显。仪表板品牌加载中最慢的十分之一从 1.7 秒降至不到半秒,而最慢的中继凭据获取则快了 7 倍。
最大的变化是您最先感受到的。在旧平台上,一个闲置过的实时连接在唤醒过程中需要约 1.2 秒才能建立。在我们自己的服务器上,它每次都只需约 0.14 秒。我们的独立可用性监控每分钟从北美检查一次 cliqer.io,结果也印证了这一点:迁移前每次检查约 750 ms,迁移后约 380 ms。
在房间内,点击本来就很快,现在依然如此。变化的是点击之外的一切:打开应用、加载演讲者页面、获取您的账户信息。这一切都响应得更快,而且每次都同样稳定。
Cloudflare 仍在为我们做什么
很多,而且我们乐于如此:
DNS
用于每一个 Cliqer 域名。
代理、CDN 和防火墙
位于 cliqer.io 前端(包括 WebSocket),并且只允许 Cloudflare 的边缘访问我们的服务器。
他们的可观测性和分析工具也让本文中的大部分诊断成为可能。我们仍然是他们的客户,也依然推荐他们。
如果连接断开,请告诉我们
我们的承诺很简单:现在当连接断开时,我们一定能找到原因。如果您发现 Cliqer 在节目中途重新连接(这里有幻灯片卡住时该怎么办的现场应对方法),请回复我们的任意一封邮件,或在应用中发起聊天。我们会阅读每一条消息,而现在,我们真的能告诉您原因了。
继续阅读
更多产品动态,助力您的下一场活动
赶在您的下一场活动之前,抢先获取下一篇指南
为演讲者、AV 团队和活动团队提供实用指南,以及真正重要的 Cliqer 版本更新。绝无垃圾邮件,一键即可退订。


