jsDelivr – 高级开源公共CDN

这是Dmitriy Akulov及其项目jsDelivr的客座文章。- 编辑注。

作为开发者,你可能已经了解了Google 托管库。Google 提供了一种简单快捷的方式,让你可以将 12 个最受欢迎的 js 库包含到你的网站中。

但是,如果你是一名网站管理员,并且想利用快速 CDN 来使用其他不太受欢迎的项目呢?或者,如果你是一名开发者,并且希望让你的项目更容易被其他用户访问和使用呢?

这就是jsDelivr发挥作用的地方。jsDelivr 是一个免费的开源 CDN,旨在帮助开发者和网站管理员。它没有受欢迎程度限制,并且允许各种类型的文件,包括 JavaScript 库、jQuery 插件、CSS 框架、字体等等。

添加库

要添加新库或更新现有库,开发者只需克隆我们的 Github 仓库,并应用他们认为合适的修改。审核员审核 Pull Request 并合并后,文件将立即从官方网站提供。

如果审核员在线,审批时间不应超过 20 分钟,否则可能需要长达 10 个小时,直到有人上线。但是,一旦我们的自动更新工具上线,审核时间将会缩短。

可靠性

但是什么让它如此先进呢?jsDelivr 的想法不是创建另一个公共 CDN,而是提供一个超快速且可靠的基础设施,让开发者和网站所有者可以信赖并使用。任何大型或小型网站都可以使用它,无需担心。没有带宽限制,我们的服务非常可靠。

我们无法容忍缓慢的响应、超时和停机,因此我们设计了一个独特的系统来克服这些问题,并提供一项产品,即使是企业级 CDN 也会感到羡慕。正常运行时间和性能是我们的首要任务,我们始终监控一切,并且始终关注可能进一步改进我们 CDN 的新技术和提供商。

基础设施

network-map

与竞争对手不同,jsDelivr 使用独特的 Multi-CDN 基础设施来提供最佳的正常运行时间和性能。它的主要骨干建立在由MaxCDN CloudFlare提供的 CDN 网络之上。

我们还在 CDN 存在很少或根本不存在的地方使用定制服务器。目前,这总共产生了 42 个全球 POP 位置。未来,我们计划添加更多位置,以即使在不太受欢迎的国家也能提供最佳性能。

当然,如果不能正确地跨多个位置进行负载均衡,那么很多位置就毫无意义。对于负载均衡系统,我们使用由Cedexis提供的服务。他们的主要功能之一是他们收集所有主要 CDN 提供商的实时性能数据。每天处理并提供给所有 Cedexis 用户 13 亿次 RUM(真实用户指标)性能测试。

衡量性能

为了收集这些 RUM 测试,他们已在数千个网站上部署了特殊的 JavaScript 代码。访问这些网站的每位访客都会执行此代码,并在浏览网站时在后台开始测试不同的 CDN 提供商。测试不会以任何方式影响浏览体验,对用户来说是完全透明的。你实际上可以通过访问我们的网站 并打开开发者工具到“网络”选项卡来查看它是如何工作的。

这些测试的妙处在于它们不是人工合成的。它们反映了真实用户从这些 CDN 中下载文件时将获得的实际性能。

然后会存储以下信息

  • 我们每个提供商的性能指标。
  • 我们每个提供商的可用性指标。
  • 浏览器的用户代理
  • 用户的 IP 地址的前三个八位字节

现在,我们拥有所有这些信息,就可以将其用于我们的智能负载均衡算法。

每个用户都会收到一个基于其位置和 ISP 提供商的唯一响应。每次用户请求从 jsDelivr 下载文件时,我们的算法都会提取其在过去几分钟内可用的性能和可用性数据,然后确定最适合该特定用户和该特定时间的最佳提供商。所有这些都在几毫秒内完成。

首先,它会确保所有可用的提供商都在线。为此,它使用 RUM 可用性数据和每分钟检查每个提供商正常运行时间的合成测试。然后,它会按用户的 ISP 及其位置的性能对提供商进行排序。

一旦它获得了最快的提供商,它就会将主机名返回给用户。因此,例如,伦敦的两名具有不同 ISP 的用户可能会收到两个不同的响应,因为他们的 ISP 对不同的 CDN 提供商具有不同的路由和性能。这个智能系统确保所有用户都能获得最大的正常运行时间和快速的加载时间。如果提供商出现故障,jsDelivr 不会出现任何问题,并将立即开始使用不同的提供商进行服务。

该算法还会立即响应性能下降。例如,一个 CDN 提供商在欧洲遭到 DDoS 攻击,他们的响应时间增加,jsDelivr 会发现这一变化,并且只是停止在欧洲使用此提供商,但仍会将其考虑用于不受攻击影响的美国和其他位置的用户。

不要依赖单个 CDN 来保证正常运行时间和速度。任何事情都有可能发生故障,但两个 CDN 和多个服务器同时发生故障的可能性非常小。这就是为什么 jsDelivr 是所有网站最优解决方案的原因。无论网站有多大。

我还应该指出,MaxCDN、CloudFlare、Cedexis 和其他公司免费赞助 jsDelivr。很高兴看到有些公司愿意帮助开源项目,并建设一个快速且免费的互联网。

高级功能

jsDelivr 还支持一些有趣且非常有用的功能,例如

版本别名

与其为每个版本使用唯一的 URL 来加载 jsDelivr 的项目,不如使用别名。例如,以 Abaaso 项目为例。目前,最新版本为 3.10.50,你可以像往常一样在 URL 中指定确切的版本来加载它。但是,由于该项目经常更新,你很快就会开始使用旧版本。为了解决这个问题,你现在只需使用以下 URL

//cdn.jsdelivr.net.cn/abaaso/3.10/abaaso.min.js

通过使用 3.10,你告诉 jsDelivr 加载它在 3.10 分支中拥有的最新版本,在本例中为 3.10.50。对于大多数作者来说,这是最佳解决方案,因为他们可以加载最新的次要版本,而无需担心可能会破坏其网站的主要更改。

当然,也可以使用以下 URL 加载 v3 分支中的最新版本

//cdn.jsdelivr.net.cn/abaaso/3/abaaso.min.js

如果出于任何原因,你需要始终加载任何主要分支中可用的最新版本,可以使用

//cdn.jsdelivr.net.cn/abaaso/latest/abaaso.min.js

通过使用latest 版本,你告诉服务器加载它拥有的绝对最新版本。当然,这很危险,而且随着时间的推移,可能会破坏你的网站。因此,请谨慎使用此功能。

使用单个 HTTP 请求加载多个文件

jsDelivr 是第一个支持此类功能的 CDN。你可以使用单个 HTTP 请求加载多个文件。类似于在自己的服务器上组合和压缩 js 文件,但由 jsDelivr 的庞大而智能的网络进行缓存。

你只需使用你想要组合的项目和文件以及它们的版本(如果需要)构建自己的 URL。例如,要加载 abaaso、ace 和 alloyui 项目的最新版本,可以使用以下语法

//cdn.jsdelivr.net.cn/g/abaaso,ace,alloyui

请注意,加载最新版本并不推荐,并且随着时间的推移,可能会破坏你的网站。因此,你应该指定确切的版本或使用版本别名

//cdn.jsdelivr.net.cn/g/jquery@2.1,angularjs@1.2

因此,jquery@2.1 将加载 2.1.0,angularjs@1.2 将加载 1.2.14。但是,上面的 URL 将加载每个项目的主文件,而不会加载其他任何内容。

如果你想要加载来自单个项目的多个文件,则可以执行以下操作

//cdn.jsdelivr.net.cn/g/jquery@2.1,angularjs@1.2.14(angular.min.js+angular-resource.min.js+angular-animate.min.js+angular-cookies.min.js+angular-route.min.js+angular-sanitize.min.js)

如果你想要加载 CSS,则使用上述格式选择 css 文件。如果组 URL 中的所有文件都具有 .css 扩展名,则服务器将自动以Content-Type: text/css HTTP 标头进行响应。在所有其他情况下(对于 /g/ URL),将使用Content-Type: application/javascript

接下来,你只需将 URL 包含在你的网站中,即可完成。更少的 DNS 解析、更少的 TCP 连接、更少的 HTTP 请求 = 更快的网站。

你甚至可以使用此功能为用户提供一个生成器,让他们能够生成包含所需模块的 URL,然后使用快速 CDN 加载所有模块。

真正的 API

jsDelivr 具有功能齐全的 API,开发者可以在其网站中使用它来创建自定义模块,以及你可能想到的任何其他内容 https://github.com/jsdelivr/api

你可以使用我们的 API 请求你需要的任何内容,而无需下载巨大的 package json。它还支持 cdnjs 和 Google。这样,开发者就拥有了构建应用程序所需的一切。

自动更新

jsDelivr libgrabber 是一种将在我们的服务器上运行的工具,如果配置了它,可以自动更新所有托管的项目。最棒的是,作者无需更改其仓库中的任何内容。所有更改都在 jsDelivr 端进行。

你只需在要让 jsDelivr 仓库中自动更新的项目中创建一个 update.json 文件,并在其中添加一些基本信息即可。该文件还支持用于新版本的多个来源,例如 npm、bower 和直接 Github 仓库。该文件仍在开发中,但计划很快发布。

试一试,伸出援助之手!

jsDelivr 是一个非常有趣的项目,我乐于开发它并使其变得更好。它也极大地依赖于社区的帮助。考虑在你的网站中使用它,并在那里托管你的项目。

如果你有兴趣提供帮助,我们随时欢迎你加入,只需加入Github上的讨论即可。

请随时发表评论,并提出你可能遇到的任何问题。

谢谢

关于 Dmitriy Akulov

系统管理员。热爱技术、高性能和快速 Web。有时假装是开发者。为 MaxCDN 工作。

Dmitriy Akulov 的更多文章…

关于 Robert Nyman [名誉编辑]

Mozilla Hacks 的技术布道者和编辑。关于 HTML5、JavaScript 和开放网络的演讲和博客。Robert 是 HTML5 和开放网络的坚定支持者,自 1999 年以来一直从事网络前端开发,在瑞典和纽约市都有工作经验。他经常在 http://robertnyman.com 上发布博客,喜欢旅行和结识新朋友。

Robert Nyman [名誉编辑] 的更多文章…


37 条评论

  1. Petter

    cedexis 测量代码是否嵌入到任何已提供的 js 中,或者 RUM 测试与已提供的内容完全独立?

    2014 年 3 月 19 日 下午 07:44

    1. Dmitriy Akulov

      RUM 测试完全独立。我们不会以任何方式修改托管文件。

      想要帮助的人可以通过将以下代码嵌入到他们的网站中来贡献性能数据
      https://github.com/jsdelivr/jsdelivr#contribute-performance-data

      2014 年 3 月 19 日 下午 07:47

  2. Fabricio C Zuardi

    我在哪里可以找到有关此 update.json 文件的更多文档或示例,以将其包含在特定项目(例如,jquery 插件)中?

    虽然 libgrabber 还没有,但公开新版本的方法是在 fork 上添加新文件夹并创建拉取请求,对吧?

    2014 年 3 月 19 日 上午 09:01

    1. Dmitriy Akulov

      README 尚未更新,但您可以查看关于 update.json 的讨论和示例,请查看 https://github.com/jsdelivr/libgrabber/issues/1

      是的,在它上线之前,我们将不得不为每个更新创建新的 PR。

      2014 年 3 月 19 日 上午 10:00

  3. Petter

    如果我想一次下载多个资源,并且不想使用 api,是否有 cdn.jsdelivr.net 的替代域?

    2014 年 3 月 19 日 上午 10:23

    1. Dmitriy Akulov

      我不知道你的意思。你能解释一下你想做什么吗?

      2014 年 3 月 19 日 上午 10:29

      1. Adarsh

        通过使用不同的域名下载不同的资源,我们可以利用浏览器并行下载资源的能力,因为可以打开到单个域名的同时连接数量通常是有限的,而且相当低。

        因此,如果您有 cdn-1.jsdelivr.net、cdn-2.jsdelivr.net 和 cdn-3.jsdelivr.net 等别名,我们可以更好地利用浏览器并行化。

        2014 年 3 月 19 日 上午 10:35

        1. Dmitriy Akulov

          我明白了。不幸的是,只有一个域可用。多 CDN 基础设施很难支持更多域。

          但是你可以使用分组功能来代替。不要并行化多个 HTTP 请求,减少 HTTP 请求。

          2014 年 3 月 19 日 上午 10:40

          1. Petter

            为什么很难?

            你可以简单地将 cdn2.jsdelivr.net 设置为 cdn.jsdelivr.net 的 CNAME,TTL 为“永远”。除非你使用它,否则不会产生任何成本。如果使用它,至少 DNS 查询不必去 DNS 负载均衡器,只需要一次 DNS 负载均衡器往返。

            2014 年 3 月 19 日 下午 17:12

        2. Paul Irish

          > 如果你有 cdn-1.jsdelivr.net、cdn-2.jsdelivr.net 和 cdn-3.jsdelivr.net 等别名,我们可以更好地利用浏览器并行化。

          域名分片在 HTTP/2 和 SPDY 中是一种反模式。因此,它即将过时。

          2014 年 3 月 19 日 下午 14:00

          1. Steve Souders

            嗨,Paul。我完全同意 HTTP2 减少了对域名分片的需要。但是,我一直在与一些早期采用者交谈,他们认为如果使用两个 TCP 连接,可能会获得更好的性能,但没有人拥有测试该假设的数据。您知道任何数据吗?

            2014 年 3 月 19 日 下午 15:38

          2. Petter

            基本的 TCP 拥塞控制是基于每个 TCP 流的等带宽共享。

            因此,当发生拥塞控制时,两个 TCP 连接将通过一个大管道获得两倍的带宽,而不会有任何奇怪的操作。

            2014 年 3 月 19 日 下午 17:06

  4. Chords

    很高兴看到我们正在支持非洲的技术基础设施。哦,等等。

    2014 年 3 月 19 日 上午 10:53

    1. Dmitriy Akulov

      我非常希望在非洲有一个 POP 位置。如果有公司在那里捐赠服务器,我会添加它。
      此外,CloudFlare 计划在今年晚些时候在南非增加一个位置。因此,jsDelivr 将自动获得它。

      2014 年 3 月 19 日 上午 10:56

  5. sokratis

    是否可以托管 Drupal 网站?它是免费的吗?

    2014 年 3 月 19 日 上午 11:34

    1. Dmitriy Akulov

      是的,它是免费的。您可以将所有托管库用于您的 Drupal 网站。

      2014 年 3 月 19 日 上午 11:49

  6. Steve Souders

    太棒了。祝贺您为开发社区推出了一个很棒的资源。我一直认为 Yahoo 的组合处理程序想法对于 CDN 来说非常棒。

    您是如何决定 1 周的 Cache-Control max-age 值的?对于完全指定的版本来说,这很棒,但如果有人使用别名,则用户可能在一周内看不到新版本。这不是世界末日,但我很好奇你是如何决定这个时间值的。

    2014 年 3 月 19 日 上午 12:11

    1. Dmitriy Akulov

      只是要澄清一下,这不是一个 Mozilla 项目 :)

      我们选择 1 周没有特别的原因。我认为这是最优值。等待文件更新 1 周并不算太久,而且足以为用户提供良好的性能体验。

      如果您认为其他值会更好,请随时在我们的 Github 仓库中打开一个 issue。

      如果您有任何其他反馈或想法,请告诉我。

      2014 年 3 月 19 日 上午 12:22

      1. Steve Souders

        对不起 Dmitriy!我错误地以为你在 Mozilla。无论如何,这是一个很棒的项目!

        我们应该看看有多少人使用别名来决定最佳缓存时间。无论如何,它可能应该根据具体程度而有所不同:完整的版本规范(“3.10.50”)应该具有非常长的缓存时间(例如,1 年),而最不具体的规范(“latest”)应该很短(例如,1 天)。

        2014 年 3 月 19 日 上午 12:35

        1. Dmitriy Akulov

          /latest/ 版本比 /g/ URL 的缓存时间更短。

          但是,是的,好主意。我将尝试根据版本优化时间。

          谢谢

          2014 年 3 月 19 日 上午 12:45

    2. Petter

      等等,对于永远不会更改的完全指定的库,有一个 1 周的 max-age?

      为什么不永远缓存?

      2014 年 3 月 19 日 下午 17:15

      1. Dmitriy Akulov

        对于静态 URL,缓存时间为 1 年。
        您可以检查不同请求的标头,例如 /g/ 和 /latest/。
        1 周是针对 /latest/ URL。

        2014 年 3 月 19 日 下午 17:19

  7. Evan Prodromou

    作为一名开源网络开发人员,我默认使用很棒的 cdnjs 服务。 http://cdnjs.com/ 用于我的网络项目 pump.io。我还贡献了一些更新和新库。

    当 cdnjs 已经存在时,为什么要使用 jsDeliver?

    2014 年 3 月 19 日 上午 12:39

    1. Dmitriy Akulov

      您可以查看 uptime 和性能统计,请查看 http://www.cdnperf.com/

      2014 年 3 月 19 日 下午 16:01

  8. Ash

    这看起来很方便。但随着这些东西越来越多,它们都变得不那么有用(它们越多,它们已经在用户缓存中的可能性就越小)。(例如,http://cdnjs.com/http://www.bootstrapcdn.com/,还有几个我记不起来)。

    但无论如何,这是一个好举动!

    2014 年 3 月 19 日 下午 15:32

  9. Brett Zamir

    非常酷。

    您是否愿意
    1. 允许完全阻止过期的 URL。
    2. 使用离线缓存清单缓存 HTML

    我一直希望有这样的资源,因为我希望看到一种(希望是暂时的)解决方法,以解决浏览器放弃 `globalStorage` 的问题:一种网站可以插入其源代码为离线缓存的 HTML 页面(理想情况下首先通过快速 CDN 提供服务)的 iframe 的方法,并向其发送 `window.postMessage()` 调用,其 JS 代码会提示用户允许读取,或者,如果允许,写入共享数据(也许还会在更新时发送发布-订阅事件),以便提供站点中立的命名空间数据或只读(按来源写入)访问其他站点的本地存储数据,并克服相同域存储限制,如果调用库将在不同域之间跳跃以重新组装其数据。

    尽管谈论“开放数据”,尽管 OS 文件系统蓬勃发展,因为它们的文件与文件创建者无关,但目前没有好的方法让项目(尤其是开源项目、非营利组织等)以一种不让他们成为守门人和单点故障的方式提供他们的数据,并且提供开箱即用的 API 来读取和可选地写入他们生成的数据,以便纯客户端 JS 应用程序可以使用它们。除了存储诸如 HTML 文档草稿或社交媒体帖子等文档的站点中立存储之外,另一个有趣的用例是针对某种类型的工具(例如基于网络的 IDE)的附加基础设施,该工具独立于特定工具的实现。

    虽然我在 https://gist.github.com/brettz9/8876920 上做了一些初步工作,但它还没有经过测试、记录或准备好,但我现在想问这些问题。

    2014 年 3 月 19 日 下午 17:23

    1. Dmitriy Akulov

      如果您愿意,可以在我们的 Github 中打开一个 issue,以便进一步讨论您的想法。

      2014 年 3 月 19 日 下午 18:07

  10. Niloy Mondal

    这个项目如何赚钱?

    2014 年 3 月 19 日 下午 22:34

    1. Dmitriy Akulov

      所有流量都由 MaxCDN、CloudFlare 和 Cedexis 等公司赞助。

      2014 年 3 月 20 日 上午 05:15

  11. Matt Freeman

    尽管我很欣赏你的动机,但技术方面存在一些缺陷。许多盒子是来自未经验证的个人捐赠的低端虚拟专用服务器,通过 LowEndBox 征集而来。我不知道这如何激发信心或信任?我认为你应该非常仔细地筛选允许参与网络的公司,我可以看到一个流氓 jQuery 很快就会出现,考虑到其中一些“系统管理员”的行为。例如,谁是 jetdino?网站上没有联系信息?公司注册?

    2014 年 3 月 19 日 晚上 11:37

    1. Dmitriy Akulov

      我拥有所有服务器的 root 访问权限,它们不共享。此外,服务器不托管文件,它们从我的源代码代理缓存文件,因此有人无法登录并修改几个文件。

      我确实会筛选所有赞助公司。此外,jetdino 最近(在我发布帖子后)因不稳定问题而被移除。

      如果您有任何疑虑,请告诉我。如果您愿意,您可以访问我们的 Github 并详细讨论我们的安全性,并可能改进一些内容。

      2014 年 3 月 20 日 上午 5:47

  12. Marcel

    用户的 IP 地址的前三个字节......以及使用 IPv6 时保存了什么?

    2014 年 3 月 21 日 上午 4:04

    1. Dmitriy Akulov

      我们不使用 Ipv6 衡量用户,因为几乎没有 CDN 支持 Ipv6。

      2014 年 3 月 21 日 上午 7:51

  13. Per Østergaard

    我如何能信任这个?只要浏览器不支持验证例如 JavaScript 的校验和,这就是让“某人”访问您网站的理想方式。这对于所有非爱好级别的网站来说都非常危险。

    2014 年 3 月 25 日 上午 8:24

    1. Dmitriy Akulov

      所有公共 CDN 都基于信任。如果您有任何想法可以改进我们的系统并赢得您的信任,请访问我们的 Github 并打开一个问题进行讨论。

      2014 年 3 月 25 日 上午 9:47

  14. Dan

    看起来不错。
    一个快速问题。任何人都可以更新现有条目吗?例如:邪恶先生可以更新托管在 CDN 上的 jquery 吗?

    2014 年 4 月 9 日 上午 6:22

    1. Dmitriy Akulov

      他可以尝试。但是我们确实会检查所有提交的文件。一旦自动更新程序上线,所有新版本将自动添加,没有任何恶意软件风险。

      2014 年 4 月 9 日 上午 7:41

本文的评论已关闭。