跳到主要内容
Deno 2.4 已发布,带来 deno bundle、字节/文本导入、OTel 稳定版等新功能
了解更多

3月2日事件更新

UTC时间周二凌晨02:01,Deno组织提供的多项服务遭遇了98分钟的服务中断。这影响了deno.land网站上的图片和视频,deno.land/x和deno.land/std上TypeScript文件的提供,doc.deno.land上的文档报告生成,以及从cdn.deno.land下载注册表元数据。我们得出结论,此次中断是由于上游服务提供商Cloudflare的滥用预防过滤器失误造成的。本文将详细说明具体发生了什么、我们如何恢复系统以及未来将采取哪些措施来防止此类事件再次发生。

目前所有服务均已恢复正常运行。api.deno.land上的注册表API未受此次事件影响。未丢失任何数据。我们高度重视此类中断事件,并对造成的不便深表歉意。

为了了解实际情况,需要说明的是,我们在事件发生前1.5小时发布了Deno 1.8,并在博客文章中公布了发行说明。这篇博客文章在大约事件发生前30分钟登上了Hacker News。事件发生时,我们网站的流量约为平时的9倍。

事件时间线

UTC时间凌晨02:00,我们收到Cloudflare自动化系统发送的邮件,通知我们deno.land上的所有媒体内容因涉嫌违反其服务条款(TOS)的第2.8节而被阻止。服务条款的这一节详细说明,Cloudflare不得主要用于提供媒体文件。收到此邮件后,我们决定从Deno 1.8的博客文章中删除屏幕截图和图片作为临时缓解措施。这于UTC时间凌晨02:09完成。但这并未解决问题。UTC时间凌晨02:22,我们向Cloudflare提交了支持工单。

UTC时间凌晨03:00,我们决定将基础设施迁移到另一个基础设施提供商(https://fly.io)以缓解中断。非常感谢Fly.io的Kurt Mackey在此次工作中提供的帮助,并立即为我们提供了基础设施。我们于UTC时间凌晨03:24切换了受影响服务的DNS记录。这使得全球大多数用户的服务中断问题于UTC时间凌晨03:41得到解决。

Cloudflare于UTC时间下午18:40解除了对我们网站的封锁——距离事件开始16.5小时,距离我们联系他们16小时。这是我们在提交工单后从他们那里收到的第一个非标准化回复。

根本原因

我们对此次事件的初步分析得出结论,Cloudflare阻止了deno.land区域的所有媒体文件——这很可能是由于Hacker News带来的流量急剧增加。单凭这一点,不应该导致deno.land/x或deno.land/std宕机,因为它们提供的是源代码而非媒体文件。这似乎是由于Cloudflare将所有.ts文件,无论其内容或内容类型标头如何,都解释为MPEG传输流(属于媒体阻止范围)造成的。在我们的案例中,这是不正确的,因为.ts文件既可以是MPEG传输流,也可以是TypeScript文件(对我们而言就是后者)。我们所有的TypeScript文件都以application/typescript类型提供服务。

影响

您可能知道,Deno使用URL导入远程代码。这意味着,如果您想要导入的模块的主机出现故障,您将无法再从该主机下载此模块。所有包管理器都有相同的问题——例如,当npmjs.org出现故障时,您就无法再执行npm install

这是否意味着当模块主机宕机时,您无法运行您的项目?不是的。Deno会将所有远程导入缓存在您系统的一个全局缓存目录中。这意味着当您第一次导入某段代码时,它会被下载并缓存,然后在后续运行中,您无需网络访问即可离线使用该代码——就像使用node_modules一样。

我们预计此次中断对大多数在活跃项目中使用Deno的开发者影响相对较小,因为他们很可能已经缓存了其依赖项。此次中断主要影响了Deno新用户和CI流水线。

同样重要的是,Deno CLI的运行并不依赖于deno.land域名保持在线。它完全是注册表无关的。如果您的项目仅由来自其他注册表(如esm.sh、skypack.dev、jspm.dev或nest.land)的模块组成,那么您将不会受到此次中断的影响。

接下来?

Cloudflare在周二晚上联系我们,讨论了事件的发生。经过初步调查,他们得出结论,这是他们滥用监控系统中的一个错误。Cloudflare已向我们保证此问题不会再次发生,他们将在其系统中实施更改,以确保此类事件不会发生在其他任何Cloudflare客户身上。

Cloudflare还向我们保证,错误检测与修复之间长达16小时的间隔是不可接受的,这将是他们立即关注的领域。

这次经历坚定了我们的信念,即在标准化、开放的Web API(如fetch)之上构建Deno运行时是正确的选择。由于Cloudflare Workers也基于这些标准Web API构建,我们能够在20分钟内将我们主要的Cloudflare Worker迁移到在Fly.io上运行的Deno脚本。我们只需对“fetch”事件进行polyfill处理,即可使我们的worker运行起来。

如果您感兴趣,这是我们用于polyfill“fetch”事件的代码:https://gist.github.com/lucacasonato/1a30a4fa6ef6c053a93f271675ef93fc。请尝试在本地运行此示例,然后访问http://0.0.0.0:8080

$ deno run --allow-net https://gist.githubusercontent.com/lucacasonato/1a30a4fa6ef6c053a93f271675ef93fc/raw/efcdc8e798604e194831830fcb962b50261384b3/example-worker.js
Listening on http://0.0.0.0:8080

由于此次事件,我们已经设置了一个公共状态页面。该页面显示了deno.land/x、deno.land/std、cdn.deno.land和api.deno.land的当前状态。您可以在https://status.deno.land/查看它。