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

2018 年 3 月 29 日

一年前的今天,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

感谢徐川对本文的审校。

2018 年 3 月 29 日 17:522122
用户头像

发布了 1008 篇内容, 共 307.0 次阅读, 收获喜欢 272 次。

关注

评论

发布
暂无评论
发现更多内容

苹果开始告别英特尔

罗燕珊

macOS Big Sur 芯片 苹果 MacBook 英特尔

监控之美——监控系统选型分析及误区探讨

华章IT

运维 云原生 监控 Prometheus

现在Php、Java、Python横行霸道的市场,C++程序员们都在干什么呢?

ShenDu_Linux

c++ 程序员 编程语言 C语言 软件工程师

架构师训练营第一期-第十周课后作业

卖猪肉的大叔

极客大学架构师训练营

shell脚本的使用该熟练起来了,你说呢?(篇二)

良知犹存

Shell

不要再满世界找linux命令了,常用的我都给你整理了

linux亦有归途

Linux 程序人生 C/C++ 后端开发 linux命令

今年最火的 Golang 云原生开源项目,可能就是它了!

孙健波

Kubernetes k8s OAM KubeVela CloudNative

区块链政务系统开发解决方案

t13823115967

区块链+ 区块链开发落地 政务系统开发解决方案

区块链供应链金融落地解决方案,数据上链存储

WX13823153201

区块链供应链金融落地

根治可扩展、高可用、高性能“神器”:SpringCloud+Nginx高并发编程手册

Java架构追梦

Java nginx 架构 面试 微服务

区块链开发落地,联盟链系统平台搭建

t13823115967

区块链 区块链开发落地 联盟链系统平台搭建

【薪火计划】06 - 你推崇的领导方式是怎么样的?

brave heart

管理

微博和B站屏蔽马保国相关信息:自媒体蹭热度要适可而止

石头IT视角

架构师训练营第一期-第十周学习总结

卖猪肉的大叔

极客大学架构师训练营

anyRTC 11月SDK更新

anyRTC开发者

flutter uni-app WebRTC RTC sdk

《华为数据之道》读书笔记:第 8 章 打造“清洁数据”的质量综合管理能力

方志

数字化转型 数据质量管理

5分钟学会6个阿里内部编程的方法

Java架构师迁哥

Spring 源码学习 02:关于 Spring IoC 和 Bean 的概念

程序员小航

spring 源码 源码分析 ioc

40 张图带你搞懂 TCP 和 UDP

云流

编程 程序员 前端 后端 网络

使用 Go 实现 Async/Await 模式

Roc

go golang channel goroutines Async

三万字无坑搭建基于Docker+K8S+GitLab/SVN+Jenkins+Harbor持续集成交付环境!!

冰河

Docker 云原生 k8s

聊聊销售背后的策略

吴晨曦

创业 销售管理

二分发代码模板

小兵

阿里云在应用扩缩容下遇到的挑战与选型思考

阿里巴巴云原生

阿里云 Kubernetes 容器 云原生

1. 揭秘Spring类型转换 - 框架设计的基石

YourBatman

Spring Framework 类型转换 Converter

Spock单元测试框架实战指南四 - 异常测试

Java老k

单元测试 spock

《华为数据之道》读书笔记:第 6 章 面向“自助消费”的数据服务建设

方志

数据中台 数据仓库 数字化转型 数据治理

前嗅教你大数据:常见几种编码介绍

前嗅大数据

大数据 编码 编码指南 前嗅大数据

阿里内部“高并发通关秘籍”曝光,看完带给你独一无二的认知!

比伯

Java 编程 架构 面试 计算机

磁盘到底是怎样工作的?一文理解硬盘结构

Guanngxu

操作系统

《华为数据之道》读书笔记:第 7章 打造“数字孪生”的数据全量感知能力

方志

数据中台 数字化转型

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