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

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

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

下面是一个例子。

\\
\// A Worker:\// 1. 把访问首页(“/”)的访问者重定向到特定国家的页面(例如,“/US/”);\// 2. 阻止盗链;\// 3. 直接从谷歌云存储提供图片服务。\addEventListener('fetch', event =\u0026gt; {\  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 \u0026amp;\u0026amp;\        new URL(referer).hostname != url.hostname) {\      return new Response(\          \"Hotlinking not allowed.\
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐