Cloudflare Workers 教程

初尝 Cloudflare Workers

使用场景

Cloudflare Workers 是 Cloudflare 提供的 serverless 计算服务。它允许您在 Cloudflare 的边缘网络上运行 JavaScript 代码,因此,代码在用户的设备和原始服务器之间的某个地方执行。由于其在全球范围内的分布和接近用户的特点,Cloudflare Workers 可以用于很多有趣和有用的应用场景。以下是一些典型的使用场景:

  1. 内容定制与A/B测试:基于用户的地理位置、浏览器类型或其他HTTP请求属性为用户提供定制内容。
  2. API代理:为API请求提供额外的安全层、调整请求和响应,或合并来自多个源的数据。
  3. 请求和响应改写:修改传入或传出的HTTP请求或响应。例如,为特定浏览器添加或修改HTTP头、添加CSP策略等。
  4. 性能优化:使用Cloudflare Workers 缓存特定的动态内容,从而减少对原始服务器的请求并加速内容传输。
  5. 身份验证和授权:在传递请求到后端之前,进行身份验证检查或添加额外的安全头。
  6. 地理定位路由:基于用户的地理位置,将其路由到最近或最佳的服务器或服务。
  7. 错误页面重定向:在原始服务器出现故障或返回错误时,为用户提供友好的错误页面或重定向到备用内容源。
  8. 机器人和威胁防御:识别和阻止恶意流量和机器人请求。
  9. 数据注入:为页面注入额外的数据或脚本,例如统计代码、广告或其他任何额外的资源。
  10. 请求日志和分析:收集有关请求和响应的数据,并将其发送到日志服务或分析工具。
  11. Serverless 应用程序:完全在Cloudflare Workers上构建应用程序,利用其低延迟、全球范围的特点。

这些只是Cloudflare Workers的一些可能的使用场景。由于它们是完全可编程的、在全球范围内分布的、具有低延迟的,因此开发人员可以为各种Web和API用途创造许多创新的解决方案。

缓存

当我们提到使用 Cloudflare Workers 来缓存特定的动态内容进行性能优化时,我们主要是指 Cloudflare 的默认缓存行为可能不会涉及某些动态内容,但使用 Workers,我们可以微调这些缓存规则,为通常不被缓存的内容添加缓存层。

下面是一些具体的步骤和考虑点,说明如何使用 Cloudflare Workers 进行这样的优化:

  1. 确定动态内容

    • 首先,识别你的站点或应用中哪些内容虽然是动态的,但其实变化不是很频繁或者在短时间内是相对稳定的。例如,某个API的响应、用户评论、产品库存状态等。
  2. 编写 Worker 脚本

    • 使用 fetch API 捕获传入的请求。
    • 在将请求转发到原始服务器之前,首先检查 Cloudflare 的缓存中是否已有该请求的响应。
    • 如果缓存中有响应,直接从缓存中返回,而不是从原始服务器获取。
    • 如果缓存中没有响应,从原始服务器获取,然后保存到 Cloudflare 的缓存中,并为其设置适当的 TTL (Time To Live)。
  3. 设置适当的TTL

    • 根据内容的动态性设置缓存时间。例如,如果你知道某个API的数据每10分钟更新一次,可以将TTL设置为10分钟或稍少一些。
  4. 考虑缓存键

    • 默认情况下,URL是用作缓存键的。但如果你想根据其他因素(如请求头或cookie值)进行微调,可以修改缓存键。
  5. 处理缓存失效

    • 如果动态内容发生了变化,考虑使用 Workers 清除或更新缓存。
    • 对于某些内容,可以使用“Cache tagging”和“Bulk purging”技术快速清除特定缓存。
  6. 避免缓存敏感信息

    • 要确保不会误缓存敏感或私有信息。例如,用户的个人信息或账单详情不应被缓存。
  7. 监控和调试

    • 使用 Cloudflare Analytics 来监控缓存命中率、缓存失效率等,确保缓存策略正常工作。

一个简单的 Cloudflare Worker 脚本示例如下:

javascript
1addEventListener('fetch', event => {
2  event.respondWith(handleRequest(event.request))
3})
4
5async function handleRequest(request) {
6  // 尝试从缓存中获取响应
7  let response = await caches.default.match(request)
8
9  // 如果缓存中没有响应,则从原始服务器获取
10  if (!response) {
11    response = await fetch(request)
12    
13    // 缓存这个响应供后续使用
14    const cacheTime = 600  // 例如:缓存10分钟
15    response = new Response(response.body, response)
16    response.headers.set('Cache-Control', `public, max-age=${cacheTime}`)
17    event.waitUntil(caches.default.put(request, response.clone()))
18  }
19
20  return response
21}

这只是一个基本的示例,实际应用中可能需要根据具体需求进行更多的微调和优化。