BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

任何人都可以借助Workers在Cloudflare上运行JavaScript了

| 作者 谢丽 关注 11 他的粉丝 发布于 2018年3月30日. 估计阅读时间: 10 分钟 | CNUTCon 了解国内外一线大厂50+智能运维最新实践案例。

一年前的今天,Cloudflare给我一项任务:让人们可以在Cloudflare的边缘服务器上运行代码。那时,我们还不知道那是什么意思。是基于容器吗?一种新的图灵不完备的领域专属语言?Lua?“函数?”我们有很多想法。

最终,我们做出了现在看来似乎很明显的选择:JavaScript,使用标准的Service Workers API,运行在一个基于V8构建的新环境中。5个月前,我们扼要介绍了我们正在构建的东西,并开始了Beta测试。

如今,Cloudflare已经部署了数以千计的脚本,并为数以十亿计的请求提供服务,Cloudflare Workers已经准备好向所有人提供服务了。

“放弃VCL并采用Cloudflare Workers让我们可以做一些创造性的路由选择,从而让我们可以比现在更快地把JavaScript交付给数以百万计的npm客户。我们将在Cloudflare平台上构建我们下一代的服务,我们将使用JavaScript实现!”

— CJ Silverio,npm公司首席技术官

什么是真正的云?

过去,Web应用程序代码分成了两部分,服务器一部分,浏览器一部分。两者之间是一个庞大的哑网络负责把数据从一个点传送到另一个点。

我们认为,这有违“云”的初衷。

我们认为,云计算真正的梦想是代码就在网络里。代码不是在“us-west-4”或“南中亚(孟买)”运行,而是随处皆可运行。

具体来说,它应该在最需要它的地方运行。在响应新西兰的用户时,代码应该在新西兰运行。在处理数据库里的数据时,代码应该在存储数据的机器上运行。在和第三方API交互时,代码应该在托管API的地方运行。当人类探险者到达火星,他们不会愿意花一个半小时的时间等待App响应——代码需要在火星上运行。

Cloudflare Workers是我们向着这个目标迈出的第一步。当你部署一个Worker时,它会在30秒之内部署到Cloudflare的整个边缘网络,全世界100多个地点。域中的每个请求都会由离用户近的Cloudflare地点的Worker来处理,不需要用户考虑自己的地点。我们上线的地点会越来越多,你的代码就越来越能“随处运行”。

好吧……我们不会在火星上运行。目前还没有。你在那里吗,艾伦?

什么是Worker?

Cloudflare Workers的名字来源于Web Workers以及更特别的Service Workers,这个W3C标准API针对的是在浏览器后台运行并拦截HTTP请求的脚本。Cloudflare Workers是使用同样的标准API编写的,但是在Cloudflare的服务器上运行,而不是在浏览器中。

下面是你需要使用的工具:

  • 运行任何JavaScript代码,使用最新的标准语言特性;
  • 拦截并修改HTTP请求,响应URL、状态、头信息和正文;
  • 直接从Worker响应请求,或者转发到其他地方;
  • 把HTTP请求发送给第三方服务器;
  • 串行或并行发送多个请求,把这些请求的响应组合成原始请求的最终响应;
  • 在响应返回给客户端以后发送异步请求(例如,记录日志或分析);
  • 控制其他Cloudflare特性,比如缓存行为。

Workers的使用方法无数,我们很希望看看我们的客户会想出什么。下面是我们在Beta测试中看到的一些方案:

  • 把不同的请求类型路由到不同的源服务器;
  • 扩展边缘服务器上的HTML模板,降低源服务器的带宽成本;
  • 针对缓存内容应用访问控制;
  • 把一小部分用户重定向到过渡服务器;
  • 在两个完全不同的后台之间执行A/B测试;
  • 构建完全依赖于Web API的“无服务器”应用程序;
  • 创建自定义的安全过滤器,阻止特定于自己App的有害流量;
  • 重写请求,提高缓存命中率;
  • 实现自定义的负载均衡和故障恢复逻辑;
  • 快速运用应用程序修复,而不必升级产品服务器;
  • 收集分析资料,而不用在用户的浏览器上运行代码;
  • 数不胜数。

下面是一个例子。

// A Worker:
// 1. 把访问首页(“/”)的访问者重定向到特定国家的页面(例如,“/US/”);
// 2. 阻止盗链;
// 3. 直接从谷歌云存储提供图片服务。
addEventListener('fetch', event => {
  event.respondWith(handle(event.request))
})

async function handle(request) {
  let url = new URL(request.url)
  if (url.pathname == "/") {
    // 这是一个首页(“/”)请求。
    // 重定向到特定国家的路径。
    // 例如,会给美国的用户发送“/US/”。
    let country = request.headers.get("CF-IpCountry")
    url.pathname = "/" + country + "/"
    return Response.redirect(url, 302)

  } else if (url.pathname.startsWith("/images/")) {
    // 这是一个图片(在“/images”目录下)请求。
    // 首先,阻止第三方访问者盗链。
    let referer = request.headers.get("Referer")
    if (referer &&
        new URL(referer).hostname != url.hostname) {
      return new Response(
          "Hotlinking not allowed.",
          { status: 403 })
    }

    // 盗链检查通过。直接从谷歌云存储提供图片服务节省服务成本。
    // 根据Cache-Control头信息,图片会在Cloudflare的边缘服务器缓存。
    url.hostname = "example-bucket.storage.googleapis.com"
    return fetch(url, request)
  } else {
    // 定期请求。转发给源服务器。
    return fetch(request)
  }
}

速度真得很快

有时候,人们问我们,是不是JavaScript很“慢”。事实是最好的证明。

Workers使用谷歌为Chrome构建的V8 JavaScript。V8不仅是JavaScript最快的实现之一,而且是任何动态类型语言的最快实现之一。人们已经针对V8做了大量的优化工作,因此,其性能几乎超过了C/C++、Rust、Go之外的任何服务器编程语言。(顺便说一下,我们很快就会支持这些语言,通过WebAssembly。)

小结:普通的Worker脚本执行时间不到1毫秒。在启用Workers时,大多数用户都无法测量出任何延迟差异——当然,除非他们的Worker在直接从边缘服务器响应时实际上提高了延迟。

关于速度,还有一个方面需要注意,Workers的部署也很快。在你保存并启用脚本后,Workers在30秒内就可以部署到全球。

定价

Workers是Cloudflare的收费扩展。我们希望定价策略尽可能的简单,就像下面这样:

每百万次请求0.50美元,每月最少5美元(包括最初的1000万请求)

入门

Everyone can now run JavaScript on Cloudflare with Workers

感谢徐川对本文的审校。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT