Cloudflare的妙用
结合 Cloudflare Workers (边缘计算), D1 (边缘数据库), 和 R2 (边缘对象存储),您可以构建功能强大、全球分布且高性能的无服务器应用程序。这些服务协同工作,让您可以在靠近用户的地方处理逻辑、存储结构化数据和存储非结构化文件。
以下是一些易于理解的例子,说明了如何结合使用它们:
### 1. 用户个人资料系统(带头像存储)
* **功能描述:** 用户可以注册,拥有个人资料信息(如用户名、邮箱、简介),并上传头像。
* **如何实现:**
* **Cloudflare Workers (逻辑处理):**
* 处理用户注册请求:验证输入,哈希密码。
* 处理用户登录请求:验证凭据,生成会话令牌 (可以存储在 D1 或 Workers KV 中)。
* 处理个人资料更新请求:验证用户身份,更新 D1 中的数据。
* 处理头像上传请求:
1. 验证用户身份。
2. 接收图片文件。
3. 生成一个唯一的对象键 (例如 `avatars/<user_id>/<timestamp>.jpg`)。
4. 将图片文件流式传输到 **R2** 存储桶。
5. 在 **D1** 中更新该用户的记录,保存头像在 R2 中的对象键。
* 处理个人资料查看请求:
1. 从 **D1** 中查询用户信息。
2. 如果用户有头像,从 D1 获取头像的 R2 对象键。
3. (可选) Worker 可以直接从 R2 获取头像并返回,或者返回一个指向 R2 公共 URL (如果配置了) 的链接。
* **Cloudflare D1 (结构化数据):**
* `users` 表:存储 `user_id`, `username`, `email_hash`, `password_hash`, `profile_bio`, `avatar_r2_key` (指向 R2 中头像的键), `created_at`, `updated_at` 等。
* **Cloudflare R2 (文件存储):**
* 存储用户上传的头像图片。每个图片以其唯一的对象键存储。
* **优势:**
* **低延迟:** 用户信息和头像都从靠近用户的边缘节点提供。
* **可扩展:** Workers, D1, R2 都能自动扩展。
* **成本效益:** R2 的零出口费用对于图片这类频繁访问的文件非常有利。
### 2. 简单的文件分享服务(带访问控制和下载统计)
* **功能描述:** 用户可以上传文件,生成一个分享链接。可以设置文件是否公开,或仅限特定用户下载。系统会统计每个文件的下载次数。
* **如何实现:**
* **Cloudflare Workers (逻辑处理 & 访问控制):**
* 处理文件上传请求:
1. (可选) 用户认证。
2. 接收文件,生成唯一的文件 ID 和 R2 对象键。
3. 将文件流式传输到 **R2**。
4. 在 **D1** 中记录文件元数据:`file_id`, `r2_object_key`, `original_filename`, `uploader_id`, `is_public` (布尔值), `allowed_user_ids` (如果非公开), `upload_date`, `download_count` (初始为 0)。
5. 返回一个分享链接 (例如 `
https://your-worker.com/share/<file_id>`)。
* 处理文件下载请求 (`/share/<file_id>`):
1. 从路径中提取 `file_id`。
2. 从 **D1** 查询该 `file_id` 的元数据。
3. 如果文件不存在,返回 404。
4. **访问控制:** 如果文件不是 `is_public`,检查当前请求用户是否有权限下载 (可能需要用户登录和会话验证)。如果无权,返回 403 Forbidden。
5. 如果允许下载,从 **R2** 获取文件对象。
6. **原子地**更新 **D1** 中该文件的 `download_count` (加 1)。
7. 将文件流式传输给用户,并设置合适的 `Content-Disposition` 头让浏览器下载。
* **Cloudflare D1 (元数据 & 统计):**
* `files` 表:`file_id` (主键), `r2_object_key`, `original_filename`, `uploader_id`, `is_public`, `allowed_user_ids_json` (存储允许用户ID的JSON数组), `upload_date`, `download_count`。
* **Cloudflare R2 (文件存储):**
* 存储用户上传的实际文件。
* **优势:**
* **精细的访问控制:** Worker 在边缘执行授权逻辑。
* **实时统计:** D1 可以快速更新和查询下载次数。
* **安全的文件存储:** R2 保护实际文件,只有通过 Worker 授权才能访问。
### 3. 动态图片缩放/处理服务
* **功能描述:** 上传一张原始图片到 R2。通过 Worker URL 请求不同尺寸或格式的图片,Worker 会从 R2 获取原图,动态处理后返回,并将处理后的版本缓存回 R2 以供后续请求。
* **如何实现:**
* **Cloudflare Workers (图片处理 & 缓存逻辑):**
* 处理图片请求 (例如 `/images/<image_id>?width=300&height=200&format=webp`):
1. 解析请求参数获取 `image_id` 和期望的尺寸/格式。
2. 生成处理后图片的 R2 缓存键 (例如 `processed/<image_id>/w300_h200.webp`)。
3. **检查 R2 中是否存在已处理的缓存版本。**
* 如果存在,直接从 **R2** 获取并返回。
4. **如果缓存不存在:**
* 从 **D1** 查询原始图片的 R2 对象键 (假设 `image_id` 对应 D1 中的一条记录,其中包含原始图片的 `r2_original_key`)。
* 从 **R2** 获取原始图片。
* **在 Worker 中使用 WebAssembly (WASM) 库 (如 `wasm-image-encoder` 或类似库) 进行图片缩放和格式转换。**
* 将处理后的图片流式传输给客户端。
* **异步地**将处理后的图片上传到 **R2** (使用之前生成的缓存键),以便下次请求时可以命中缓存。
* **Cloudflare D1 (原始图片元数据):**
* `original_images` 表:`image_id` (主键), `r2_original_key` (原始图片在R2中的键), `original_filename`, `uploader_id`, `upload_date`。
* **Cloudflare R2 (文件存储):**
* 存储原始上传的图片。
* 存储 Worker 动态生成并缓存的各种尺寸/格式的图片。
* **优势:**
* **按需处理:** 只在首次请求特定尺寸时处理图片,节省计算资源。
* **边缘缓存:** 处理后的图片缓存在 R2,后续请求极快。
* **节省存储:** 只需存储原始图片,按需生成变体。
* **零出口费用:** 大量图片传输的成本显著降低。
### 4. 简单的博客或内容发布平台
* **功能描述:** 管理员可以创建和发布文章(文本内容)。文章可以包含图片。
* **如何实现:**
* **Cloudflare Workers (内容服务 & 管理接口):**
* **管理端点 (受保护):**
* 创建/编辑文章:接收文章标题、Markdown/HTML 内容,将其存储到 **D1**。
* 上传文章图片:接收图片,存到 **R2**,返回图片在 R2 中的 URL 或键,供管理员插入文章内容中。
* **公共端点 (查看文章):**
* 接收文章 slug 或 ID。
* 从 **D1** 查询文章内容。
* 将文章内容(可能需要将 Markdown 转换为 HTML)返回给用户。
* 文章中引用的图片 URL 可以直接指向 R2 (如果 R2 存储桶已通过自定义域公开) 或通过 Worker 代理从 R2 获取。
* **Cloudflare D1 (结构化内容):**
* `posts` 表:`post_id` (主键), `slug`, `title`, `content` (Markdown 或 HTML), `author_id`, `publish_date`, `status` (draft/published)。
* (可选) `images` 表:`image_id`, `r2_key`, `caption`, `post_id` (外键,如果图片与特定文章关联)。
* **Cloudflare R2 (媒体文件):**
* 存储文章中使用的所有图片和其他媒体文件。
* **优势:**
* **快速内容交付:** 文章数据和图片都从边缘提供。
* **简单的 CMS 后端:** Worker 和 D1 构成了轻量级的内容管理系统。
* **全球一致性:** D1 保证了文章数据在不同边缘位置的一致性。
这些例子展示了 Workers 作为业务逻辑处理层,D1 作为结构化元数据和状态存储,R2 作为大规模文件存储的组合威力。它们共同使得在 Cloudflare 边缘构建全功能、高性能且经济高效的应用程序成为可能。