ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Cloudflare Workers Smart Placement 实战模式指南:从数据库后端到前后端分离的完整架构方案

Cloudflare Workers Smart Placement 实战模式指南:从数据库后端到前后端分离的完整架构方案 Cloudflare Workers Smart Placement 实战模式指南从数据库后端到前后端分离的完整架构方案【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skillsCloudflare Workers Smart Placement 是一项自动化的负载放置优化机制它不再默认把请求路由到离用户最近的边缘节点而是通过分析 Worker 的请求耗时分布把 Worker 的fetch处理逻辑自动运行到离后端基础设施数据库、API 等更近的数据中心从而显著降低端到端请求延迟。本篇指南以 patterns.md 为核心系统讲解五种经过验证的部署模式数据库后端、前后端分离、外部 API 集成、SSR/API 网关、Durable Objects 协调者以及必须避开的 RPC 陷阱和最佳实践读完即可在你的 Cloudflare Workers 项目中落地并验证 Smart Placement。相关配套文档本指南与 README.md概念与决策树、configuration.mdwrangler.jsonc 配置、api.md状态 API 与监控、gotchas.md故障排查共同构成完整参考部署层面可参照仓库技能入口 SKILL.md。一、模式一带数据库访问的后端 WorkerBackend Worker with Database Access这是最直接的 Smart Placement 应用场景一个 Worker 的fetch处理函数直接访问 D1 数据库。此时 Worker 的主要耗时来自数据库往返而非用户到边缘的网络延迟因此把 Worker 运行位置向数据库靠拢是最优解。export default { async fetch(request: Request, env: Env): PromiseResponse { const user await env.DATABASE.prepare(SELECT * FROM users WHERE id ?).bind(userId).first(); const orders await env.DATABASE.prepare(SELECT * FROM orders WHERE user_id ?).bind(userId).all(); return Response.json({ user, orders }); } };对应的wrangler.jsonc配置{ placement: { mode: smart }, d1_databases: [{ binding: DATABASE, database_id: xxx }] }配置要点解读placement.mode: smart开启自动优化off或省略该字段则显式/隐式禁用Worker 始终运行在离用户最近的边缘节点详见 configuration.md 的 Mode 取值表d1_databases.binding定义了 Worker 代码中访问数据库的环境变量名DATABASEdatabase_id指向具体的 D1 数据库实例代码中使用prepare(...).bind(...).first()/.all()的链式调用执行参数化 SQL 查询——bind()传入参数、first()取首行、all()取全部行这是 D1 的标准查询 API也可参考 bindings/patterns.md 中的并行访问示例Promise.all进一步压榨延迟。从源码结构看Smart Placement 的核心约束是它只影响默认导出export default的fetch处理函数。这个 Worker 完全符合条件因此启用的收益最大——文档中记录的典型收益是数据库密集型 Worker 的请求时长降低 20%50%。二、模式二前后端分离Frontend Backend Split via Service Bindings全栈应用的最佳架构是把单体 Worker 拆成两个 Worker各司其职前端 Worker运行在边缘紧贴用户负责快速响应用户请求后端 Worker开启 Smart Placement运行在数据库附近负责数据访问。User → Frontend Worker (at edge, close to user) ↓ Service Binding Backend Worker (Smart Placement enabled, close to DB/API) ↓ Database/Backend Service2.1 前端 Worker路由到后端// Frontend Worker - routes requests to backend interface Env { BACKEND: Fetcher; // Service Binding to backend Worker } export default { async fetch(request: Request, env: Env): PromiseResponse { if (new URL(request.url).pathname.startsWith(/api/)) { return env.BACKEND.fetch(request); // Forward to backend } return new Response(Frontend content); } };2.2 后端 Worker数据库操作// Backend Worker - database operations interface BackendEnv { DATABASE: D1Database; } export default { async fetch(request: Request, env: BackendEnv): PromiseResponse { const data await env.DATABASE.prepare(SELECT * FROM table).all(); return Response.json(data); } };2.3 两端的 wrangler.jsonc 配置// frontend-worker/wrangler.jsonc { name: frontend, main: frontend-worker.ts, // No placement - runs at edge services: [ { binding: BACKEND, service: backend-api } ] }// backend-api/wrangler.jsonc { name: backend-api, main: backend-worker.ts, placement: { mode: smart }, d1_databases: [ { binding: DATABASE, database_id: xxx } ] }前端 Worker 不配置placement字段即默认留在边缘后端 Worker 配置mode: smart。前端通过services声明的 Service Binding绑定名BACKEND目标服务backend-api调用后端。正如 bindings/patterns.md 所指出的Service Binding 路由只依赖绑定名URL 的 hostname 可以随意填写如https://fake-host且调用发生在同一隔离环境内、免费且无 DNS 开销。2.4 CRITICAL必须使用 fetch 型 Service Binding而非 RPC关键约束CRITICAL只有基于fetch的 Service Binding 才能被 Smart Placement 优化。如果使用WorkerEntrypoint的 RPC 调用Smart Placement不会优化那些方法调用——只有fetch处理函数受影响。// ❌ RPC - Smart Placement has NO EFFECT on backend RPC methods export class BackendRPC extends WorkerEntrypoint { async getData() { // ALWAYS runs at edge, Smart Placement ignored return await this.env.DATABASE.prepare(SELECT * FROM table).all(); } } // ✅ Fetch - Smart Placement WORKS export default { async fetch(request: Request, env: Env): PromiseResponse { // Runs close to DATABASE when Smart Placement enabled const data await env.DATABASE.prepare(SELECT * FROM table).all(); return Response.json(data); } };根本原因从源码约束推断RPC 调用绕过fetch处理函数而 Smart Placement 只能路由fetch请求。同理命名入口除default外的其他导出、队列消费者、定时触发器scheduled等事件类型同样不受影响。这一点在 configuration.md 与 gotchas.md 中被反复强调是最常见的开了 Smart Placement 却无效的根因。解决方案把 RPC 方法改造成 fetch 端点或者用一个带fetch处理函数的包装 Worker 去调用后端 RPC会额外增加一层延迟非首选。注意Durable Objects 的 RPC如stub.increment()属于另一套机制与 Smart Placement 的取舍可参考 durable-objects/patterns.md。三、模式三外部 API 集成External API Integration当 Worker 需要聚合多个外部第三方 API 的响应时后端延迟第三方 API 往返占据主导地位同样适合 Smart Placement。export default { async fetch(request: Request, env: Env): PromiseResponse { const apiUrl https://api.partner.com; const headers { Authorization: Bearer ${env.API_KEY} }; const [profile, transactions] await Promise.all([ fetch(${apiUrl}/profile, { headers }), fetch(${apiUrl}/transactions, { headers }) ]); return Response.json({ profile: await profile.json(), transactions: await transactions.json() }); } };要点使用Promise.all并行发起多个独立的fetch调用避免串行等待与 bindings/patterns.md 的并行访问最佳实践一致env.API_KEY来自 Secrets 绑定切勿硬编码到代码或vars配置中。设置方式为npx wrangler secret put API_KEY详见 bindings/patterns.md 的 Secrets Management 一节如果外部 API 自身具备全球多地域分布、各地域延迟差异不大Smart Placement 的收益会变小对应后端服务全球分布则无单一最优位置的判定此时需结合监控指标决定是否保留。文档记载对发起多个后端 API 调用的 WorkerSmart Placement 典型的请求时长降幅可达 30%60%。四、模式四SSR / API 网关模式SSR / API Gateway Pattern把鉴权、路由等贴近用户的逻辑留在边缘前端把数据库读取等贴近数据的逻辑放到 Smart Placement 后端天然构成 SSR服务端渲染或 API 网关架构。// Frontend (edge) - auth/routing close to user export default { async fetch(request: Request, env: Env) { if (!request.headers.get(Authorization)) { return new Response(Unauthorized, { status: 401 }); } const data await env.BACKEND.fetch(request); return new Response(renderPage(await data.json()), { headers: { Content-Type: text/html } }); } }; // Backend (Smart Placement) - DB operations close to data export default { async fetch(request: Request, env: Env) { const data await env.DATABASE.prepare(SELECT * FROM pages WHERE id ?).bind(pageId).first(); return Response.json(data); } };设计逻辑前端边缘先做鉴权检查Authorization头失败直接返回 401避免把无效请求转发到后端通过env.BACKEND.fetch(request)把请求转给后端拿到 JSON 后用renderPage()渲染成 HTML 返回。鉴权、重定向、简单变换等纯边缘逻辑不应开启 Smart Placement——它们没有后端通信留在用户附近最快后端Smart Placement只负责参数化查询数据库并返回 JSONSmart Placement 会把它放到离数据库更近的位置缩短数据库往返。这一模式与文档中的推荐架构图完全一致User → Frontend Worker (edge) → Backend Worker (Smart Placement) → Database同时保留了前端响应快 后端延迟低两个优点。五、模式五Durable Objects 与 Smart Placement 的协同Durable Objects with Smart Placement5.1 关键原则Smart Placement 不控制 DO 的运行位置核心原则Smart Placement不决定 Durable ObjectsDO在哪里运行。DO 始终运行在指定区域由 jurisdiction 或 smart location hints 决定。Smart Placement 实际影响的是协调者 Worker 中调用多个 DO 的fetch处理函数的位置。5.2 聚合多个 DO 的协调者 Worker模式在聚合多个 DO 数据的协调者 Worker 上启用 Smart Placement// Worker with Smart Placement - aggregates data from multiple DOs export default { async fetch(request: Request, env: Env): PromiseResponse { const userId new URL(request.url).searchParams.get(user); // Get DO stubs const userDO env.USER_DO.get(env.USER_DO.idFromName(userId)); const analyticsID env.ANALYTICS_DO.idFromName(analytics-${userId}); const analyticsDO env.ANALYTICS_DO.get(analyticsID); // Fetch from multiple DOs const [userData, analyticsData] await Promise.all([ userDO.fetch(new Request(https://do/profile)), analyticsDO.fetch(new Request(https://do/stats)) ]); return Response.json({ user: await userData.json(), analytics: await analyticsData.json() }); } };对应的wrangler.jsonc// wrangler.jsonc { placement: { mode: smart }, durable_objects: { bindings: [ { name: USER_DO, class_name: UserDO }, { name: ANALYTICS_DO, class_name: AnalyticsDO } ] } }代码拆解env.USER_DO.idFromName(userId)通过名称生成确定性的 DO IDidFromName保证同一名称映射到同一 DO适用于按用户/会话分片的场景参见 durable-objects/patterns.md 的 ID 策略表env.USER_DO.get(id)获取 DO stub然后userDO.fetch(new Request(...))以 HTTP 语义调用 DO 的fetch处理器这正是 Smart Placement 能够感知的调用路径而stub.increment()这类 RPC 属于另一套机制Promise.all并行拉取多个 DO 的数据最后聚合为 JSON 响应。5.3 什么时候有帮助 / 什么时候没用有帮助的场景Worker 的fetch处理函数运行位置更靠近 DO 所在区域减少多次 DO 调用的网络延迟DO 在地理上集中、或位于特定司法管辖区jurisdiction时收益最大协调者需要发起大量串行或并行的 DO 调用时收益明显。没有帮助的场景DO 全球分布不存在单一最优的 Worker 位置Worker 只调用单个 DODO 调用频率很低或结果已被缓存。六、最佳实践总结与反模式Best Practices应当做Do前后端分离全栈应用拆成前端在边缘 后端 Smart Placement两个 Worker保持前端响应速度的同时优化后端延迟使用 fetch 型 Service Binding而非 RPC——这是 Smart Placement 生效的前提为后端逻辑开启API、数据聚合、数据库操作等后端型 Worker耐心等待分析启用后等待 15 分钟以上让系统完成流量分析并通过 API 验证placement_status SUCCESS。不要做Dont纯静态内容或缓存响应的 Worker 不要开——静态资源应始终从离用户最近的边缘提供纯边缘逻辑鉴权、重定向、简单变换不要开RPC 方法不要指望被优化Pages / Assets 且run_worker_first true的 Worker绝对不要开——Smart Placement 会把所有请求包括 HTML/CSS/JS/图片路由到远端导致静态资源加载慢 25 倍这是文档中标记为最常见且影响最大的误配置。正确做法是拆分前端 Worker 保留assets.run_worker_first: true且不配 placement后端 Worker 单独开 Smart Placement见 configuration.md。验证流程启用后必做# 部署 wrangler deploy # 查看 placement_status应为 SUCCESS curl -H Authorization: Bearer $TOKEN \ https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/services/$WORKER_NAME \ | jq .result.placement_status # 监控带 cf-placement 头跟踪路由决策 wrangler tail your-worker-name --header cf-placement状态值速查状态含义处理undefined缺失尚未分析Worker 运行在默认边缘位置等待 15 分钟分析完成SUCCESS分析完成Smart Placement 已生效Worker 运行在最优位置持续监控指标INSUFFICIENT_INVOCATIONS流量不足无法做放置决策保证来自全球多区域的持续流量后重试UNSUPPORTED_APPLICATION罕见1%反而变慢了已自动回退到边缘禁用 Smart Placement排查是否适用其中cf-placement响应头格式为{placement-type}-{IATA-code}remote-*表示被 Smart Placement 路由到远端local-*表示留在默认边缘IATA 码是最近机场代码如remote-LHR表示路由到伦敦。注意该头是 Beta 特性可能随时变更或移除详见 api.md。两条容易忽略的注意事项1% 基线流量Smart Placement 会自动把约 1% 的请求按未优化方式路由作为性能对比基线这是预期行为不是故障本地开发无效Smart Placement 在wrangler dev本地中不会生效只能通过部署到生产或 staging 环境验证wrangler deploy --env staging。Wrangler 版本要求 2.20.0所有 Workers 套餐Free、Paid、Enterprise均可用见 gotchas.md。性能判断指标在 Dashboard 的Workers Pages → [你的 Worker] → Metrics → Request Duration查看直方图对比开启 Smart Placement99% 流量与1% 基线流量的请求时长WITH WITHOUT说明在起作用、保持开启WITH ≈ WITHOUT说明中性、可考虑关闭以节省资源WITH WITHOUT说明在拖慢性能应通过{ placement: { mode: off } }或删除placement字段显式关闭。这里要区分两个指标Request duration请求到达至响应返回的总时间含网络延迟用它衡量 Smart Placement 效果与Execution duration代码实际执行时间不含网络等待。【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表