就在一年前的今天,Cloudflare给了我一个使命:允许人们在Cloudflare的网路运行代码。当时,我们还不知道这意味着什么。它会以容器为基础吗?一种新的图灵不完全的领域特定语言?Lua语言?“函数”?我的脑中涌出很多想法。

最终,我们做出了现在看似理所当然的选择:JavaScript,使用标准的Service Workers API,在基于V8构建的新环境中运行。五个月前,我们向您预览了我们正在构建的内容,并开始了测试。

如今,部署了数千个脚本,又处理了数十亿的请求之后,Cloudflare Workers已经为所有人做好了准备。

“脱离可视化组件库(Visual Component Library,VCL)并采用Cloudflare Workers将允许我们做一些创意路由,这将让我们以比现在更快的速度向npm的数百万用户提供JavaScript。我们将在Cloudflare平台上构建我们的下一代服务,我们将用JavaScript来完成这一点!”

- CJ Silverio,首席技术官,npm,Inc。

云到底是什么?

从历史上看,Web应用程序代码已在服务器和浏览器之间分配。它们之间存在着一个巨大的但本质上很简单的网络——点到点传送数据的网络。

我们认为这并不是“云计算”目的。

云计算的真正目的是使得您的代码在它本身的网络中运行。您的代码并非运行在“us-west-4”或“South China Asia(Mumbai)”中,而是无处不在

更具体地说,它应该在最需要的地方运行。在向新西兰的用户响应时,您的代码应该在新西兰运行。在数据库中处理数据时,代码应该在存储数据的计算机上运行。在与第三方API交互时,您的代码应该在托管API的任何位置运行。当人类探险家到达火星时,他们不会乐意用半个小时等待您的应用程序响应——您的代码也需要在火星上运行。

Cloudflare Workers是迈向这一愿景的第一步。当您部署Worker时,它将在30秒内部署到Cloudflare遍布全球100多个地点的整个边缘网络。您的域名的每个请求都将由您的工作人员在靠近最终用户的Cloudflare位置处理,您无需考虑个别位置。我们在线提供的位置越多,您的代码就越“无处不在”。

什么是Worker?

Cloudflare Workers的名称来自Web Workers,更具体地说是Service Workers,一个用于在web浏览器后台运行并拦截HTTP请求的脚本的W3C标准API。Cloudflare Workers是针对相同的标准API编写的,但是是在Cloudflare的服务器上运行,而不是在浏览器中运行。

以下是您可以使用的工具:

  • 使用最新的标准语言功能执行任意JavaScript代码。
  • 拦截和修改HTTP请求和响应URL,状态,标头和正文内容。
  • 直接从您的Worker响应请求,或将其转发到其他地方。
  • 将HTTP请求发送到第三方服务器。
  • 以串行或并行方式发送多个请求,并使用响应组成对原始请求的最终响应。
  • 在响应已经返回到客户端之后发送异步请求(例如,用于记录或分析)。
  • 控制其他Cloudflare功能,例如缓存行为。

Workers的用途是无限的,我们很高兴能看到我们的客户提议了什么。以下是我们在测试版中看到的一些想法:

  • 将不同类型的请求按路线发送到不同的源服务器。
  • 在边缘网络展开HTML模板,以降低原始带宽成本。
  • 将访问控制应用于缓存的内容。
  • 将一小部分用户重定向到开发用服务器。
  • 在两个完全不同的后端之间执行A / B测试。
  • 构建完全依赖Web API的“无服务器”应用程序。
  • 创建自定义安全过滤器以阻挡应用程序独有的不需要的流量
  • 重写请求以提高缓存命中率。
  • 实现自定义负载均衡和容错逻辑。
  • 无需更新生产服务器即可快速修复应用程序。
  • 无需在用户的浏览器中运行代码即可收集分析。
  • 还有很多。

以下是一个例子。

// A Worker which:
// 1. Redirects visitors to the home page ("/") to a
//    country-specific page (e.g. "/US/").
// 2. Blocks hotlinks.
// 3. Serves images directly from Google Cloud Storage.
addEventListener('fetch', event => {
  event.respondWith(handle(event.request))
})

async function handle(request) {
  let url = new URL(request.url)
  if (url.pathname == "/") {
    // This is a request for the home page ("/").
    // Redirect to country-specific path.
    // E.g. users in the US will be sent to "/US/".
    let country = request.headers.get("CF-IpCountry")
    url.pathname = "/" + country + "/"
    return Response.redirect(url, 302)

  } else if (url.pathname.startsWith("/images/")) {
    // This is a request for an image (under "/images").
    // First, block third-party referrers to discourage
    // hotlinking.
    let referer = request.headers.get("Referer")
    if (referer &&
        new URL(referer).hostname != url.hostname) {
      return new Response(
          "Hotlinking not allowed.",
          { status: 403 })
    }

    // Hotlink check passed. Serve the image directly
    // from Google Cloud Storage, to save serving
    // costs. The image will be cached at Cloudflare's
    // edge according to its Cache-Control header.
    url.hostname = "example-bucket.storage.googleapis.com"
    return fetch(url, request)
  } else {
    // Regular request. Forward to origin server.
    return fetch(request)
  }
}

这真的很快

有时人们问我们JavaScript是否“很慢”,事实远非如此!

Workers使用Google为Chrome构建的V8 JavaScript引擎。V8不仅最快实现了JavaScript,同时最快实现了动态类型语言。由于对V8进行了大量优化工作,它的性能几乎胜过任何流行的服务器编程语言,除了C / C ++,Rust和Go。(顺便说一句,我们很快就会通过WebAssembly允许使用这些语言。)

起步效率:典型的Worker脚本可以在不到一毫秒的时间内执行。大多数用户在启用Workers时无法测量到任何延迟差异——当然,除非他们的worker通过直接从边缘响应来改善延迟。

在另一个速度相关的说明中,Worker也实现了快速部署。从保存和启用脚本开始,Workers在30秒内便完成了全局部署

定价

Workers是Cloudflare的付费附加组件。我们希望尽可能简化定价,所以定价是这样:

启用

“Cloudflare Workers为我们节省了大量时间。在没有工作人员的情况下管理僵尸网络流量会消耗宝贵的开发和服务器资源,而这些资源最好花在别处。”

- MaxMind高级系统管理员John Thompson

关键词:产品新闻WorkersJavaScript性能压缩开发人员无服务器