跳转到内容
搜索文档

放置

最后更新 查看 MarkdownAgent 设置

默认情况下,WorkersPages Functions 会在距离接收请求位置最近的数据中心运行。如果您的 Worker 需要请求后端基础设施(如数据库或 API),将该 Worker 部署在更靠近后端而非最终用户的位置,可能会获得更好的性能。

{
	"placement": {
		// Use one of the following options (mutually exclusive):
		"mode": "smart", // Cloudflare automatically places your Worker closest to the upstream with the most requests
		"region": "gcp:us-east4", // Explicit cloud region to run your Worker closest to - e.g. "gcp:us-east4" or "aws:us-east-1"
		"host": "db.example.com:5432", // A host to probe (TCP/layer 4) - e.g. a database host - and place your Worker closest to
		"hostname": "api.example.com", // A hostname to probe (HTTP/layer 7) - e.g. an API endpoint - and place your Worker closest to
	},
}
[placement]
mode = "smart"
region = "gcp:us-east4"
host = "db.example.com:5432"
hostname = "api.example.com"

放置功能可以通过减少 Worker 与后端服务之间请求的往返延迟,降低 Worker 请求的整体延迟。对于运行在传统云基础设施中的数据库、API 和其他服务,您可以将延迟降至个位数毫秒级别。

选项 适用场景 配置
Smart(智能) 多个后端服务,或基础设施位置未知 mode = "smart"
Region 单个后端服务位于已知的云区域 region
Host 单个后端服务不在主流云提供商中 hosthostname

了解放置

假设一位位于澳大利亚悉尼的用户访问运行在 Workers 上的应用程序。该应用程序需要多次往返访问位于德国法兰克福的数据库。

一位位于澳大利亚悉尼的用户连接到同一区域的 Worker,该 Worker 随后多次往返访问位于德国法兰克福的数据库。

悉尼与法兰克福之间多次往返的延迟会不断累加。通过将 Worker 部署在数据库附近,Cloudflare 可以缩短请求的总耗时。

一位位于澳大利亚悉尼的用户连接到位于德国法兰克福的 Worker,该 Worker 随后多次往返访问同样位于德国法兰克福的数据库。

启用 Smart Placement

Smart Placement 会自动分析 Worker 的流量模式,并将其放置在最佳位置。在以下情况下使用 Smart Placement:

  • Worker 连接多个后端服务
  • 您不知道基础设施的确切位置
  • 后端服务是分布式或复制的

Smart Placement 按 Worker 分别启用。启用后,它会定期分析 Worker 在不同 Cloudflare 位置的请求持续时间

对于每个候选位置,Smart Placement 会考虑 Worker 的性能以及转发请求所增加的网络延迟。如果某个候选位置明显更快,请求会被转发到该位置。否则,Worker 会在距离请求最近的默认位置运行。

Smart Placement 仅考虑 Worker 此前运行过的位置。它无法将 Worker 放置在通常不会收到流量的位置。

了解限制

启用 smart placement

Smart Placement 适用于所有 Workers 套餐。

使用 Wrangler 配置

在 Wrangler 配置文件中添加以下内容:

{
	"placement": {
		"mode": "smart",
	},
}
[placement]
mode = "smart"

Smart Placement 在部署后可能需要最多 15 分钟来分析 Worker。

在仪表板中配置

  1. 前往 Workers & Pages

    Go to Workers & Pages ↗
  2. 选择您的 Worker。

  3. 前往 Settings(设置) > General

  4. Placement(放置) 下,选择 Smart(智能)

Smart Placement 需要来自多个位置对 Worker 的稳定流量才能做出放置决策。分析过程可能需要最多 15 分钟。

检查放置状态

通过 Workers API 查询 Worker 的放置状态:

curl -X GET https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/services/$WORKER_NAME \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" | jq .

可能的放置状态:

状态 说明
(不存在) Worker 尚未被分析。它在距离请求最近的默认位置运行。
SUCCESS Worker 已被分析,将由 Smart Placement 进行优化。
INSUFFICIENT_INVOCATIONS Worker 尚未收到来自多个位置的足够请求,无法做出放置决策。
UNSUPPORTED_APPLICATION Smart Placement 使 Worker 变慢并已恢复默认放置。此状态较为罕见(少于 1% 的 Worker)。

查看请求持续时间分析

启用 Smart Placement 后,系统会收集请求持续时间数据。请求持续时间在距离最终用户最近的数据中心测量。默认情况下,1% 的请求不会通过 Smart Placement 路由,以作为对比基准。

查看 Worker 的请求持续时间分析,以衡量 Smart Placement 的影响。

检查 cf-placement 标头

启用放置后,Cloudflare 会在所有请求中添加 cf-placement 标头。使用此标头可以检查请求是否通过 Smart Placement 路由,以及 Worker 在何处处理了请求。

标头值包含放置类型和表示数据中心位置的机场代码:

  • remote-LHR — 请求通过 Smart Placement 路由到伦敦附近的数据中心。
  • local-EWR — 请求未通过 Smart Placement 路由。Worker 在纽瓦克附近的默认位置运行。

配置显式 Placement Hints

Placement Hints 允许您显式指定 Worker 的运行位置。在以下情况下使用 Placement Hints:

  • 您知道后端基础设施的确切位置
  • Worker 连接单个数据库、API 或服务
  • 基础设施是单点部署(未复制或使用 anycast)

示例包括特定区域中的主数据库、虚拟机或 Kubernetes 集群。将每次查询 20 到 30 毫秒的往返延迟降至 1 到 3 毫秒,可以改善响应时间。

指定云区域

如果您的基础设施运行在 AWS、GCP 或 Azure 上,请使用 {provider}:{region} 格式设置 placement.region 属性:

{
	"placement": {
		"region": "aws:us-east-1", // Explicit cloud region to run your Worker closest to - e.g. "gcp:us-east4" or "aws:us-east-1"
	},
}
[placement]
region = "aws:us-east-1"

Cloudflare 会将您指定的云区域映射到与该区域延迟最低的数据中心。Cloudflare 会自动调整放置以应对网络维护或变更,因此您无需指定故障转移区域。

指定主机端点

如果您的基础设施不在主流云提供商中,您可以指定一个端点供 Cloudflare 探测。Cloudflare 将三角定位外部主机的位置,并将 Workers 放置在附近的区域。

placement.host 设置为标识第 4 层服务。Cloudflare 使用 TCP CONNECT 检查来测量延迟,并选择最佳数据中心。

{
	"placement": {
		"host": "my_database_host.com:5432", // A host to probe (TCP/layer 4) - e.g. a database host - and place your Worker closest to
	},
}
[placement]
host = "my_database_host.com:5432"

placement.hostname 设置为标识第 7 层服务。Cloudflare 使用 HTTP HEAD 检查来测量延迟,并选择最佳数据中心。

{
	"placement": {
		"hostname": "my_api_server.com", // A hostname to probe (HTTP/layer 7) - e.g. an API endpoint - and place your Worker closest to
	},
}
[placement]
hostname = "my_api_server.com"

探测从公共 IP 范围发送,而非 Cloudflare IP 范围。Cloudflare 会定期重新检查服务位置。这些探测用于定位单点部署的资源,对广播、anycast、多播或复制资源无法正确工作。

列出支持的区域

Placement Hints 支持 Amazon Web Services (AWS)、Google Cloud Platform (GCP) 和 Microsoft Azure 区域标识符:

提供商 格式 示例
AWS aws:{region} aws:us-east-1aws:us-west-2aws:eu-central-1
GCP gcp:{region} gcp:us-east4gcp:europe-west1gcp:asia-east1
Azure azure:{region} azure:westeuropeazure:eastusazure:southeastasia

有关完整区域代码列表,请参阅 AWS 区域GCP 区域Azure 区域

放置行为

无论使用 Smart Placement 还是 Placement Hints,Workers 放置的行为方式类似。以下行为对两者均适用。

了解限制

以下限制同时适用于 Smart Placement 和 Placement Hints:

cf-placement 标头

启用放置后,Cloudflare 会在所有请求中添加 cf-placement 标头。使用此标头可以检查请求是否通过放置功能路由,以及 Worker 在何处处理了请求。

标头值包含放置类型和表示数据中心位置的机场代码:

  • remote-LHR — 请求通过 Smart Placement 路由到伦敦附近的数据中心。
  • local-EWR — 请求未通过 Smart Placement 路由。Worker 在纽瓦克附近的默认位置运行。

多个 Workers

如果您在 Workers 上构建全栈应用程序,请将边缘逻辑(身份验证、路由)和后端逻辑(数据库查询、API 调用)拆分为独立的 Workers。使用 Service Bindings 通过类型安全的 RPC 连接它们。

Smart Placement 和 Service Bindings

在后端 Worker 上启用放置功能,使其在靠近数据库的位置被调用,而边缘 Worker 则在靠近用户的位置处理身份验证。

示例:边缘身份验证与已放置的后端

此示例展示两个 Workers:

  • auth-worker — 在边缘运行(无放置),处理身份验证
  • app-worker — 部署在数据库附近,处理数据查询
{
	"name": "auth-worker",
	"main": "src/index.ts",
	"services": [{ "binding": "APP", "service": "app-worker" }],
}
name = "auth-worker"
main = "src/index.ts"

[[services]]
binding = "APP"
service = "app-worker"
auth-worker/src/index.tsts
import { AppWorker } from "../app-worker/src/index";

interface Env {
	APP: Service<AppWorker>;
}

export default {
	async fetch(request: Request, env: Env): Promise<Response> {
		const authHeader = request.headers.get("Authorization");
		if (!authHeader?.startsWith("Bearer ")) {
			return new Response("Unauthorized", { status: 401 });
		}

		const userId = await validateToken(authHeader.slice(7));
		if (!userId) {
			return new Response("Invalid token", { status: 403 });
		}

		// Call the placed back-end Worker via RPC
		const data = await env.APP.getUser(userId);
		return Response.json(data);
	},
};

async function validateToken(token: string): Promise<string | null> {
	return token === "valid" ? "user-123" : null;
}
{
	"name": "app-worker",
	"main": "src/index.ts",
	"placement": {
		// Use one of the following options (mutually exclusive):
		// "mode": "smart", // Cloudflare automatically places your Worker closest to the upstream with the most requests
		"region": "aws:us-east-1", // Explicit cloud region to run your Worker closest to - e.g. "gcp:us-east4" or "aws:us-east-1"
		// "host": "db.example.com:5432", // A host to probe (TCP/layer 4) - e.g. a database host - and place your Worker closest to
		// "hostname": "api.example.com", // A hostname to probe (HTTP/layer 7) - e.g. an API endpoint - and place your Worker closest to
	},
}
name = "app-worker"
main = "src/index.ts"

[placement]
region = "aws:us-east-1"
app-worker/src/index.tsts
import { WorkerEntrypoint } from "cloudflare:workers";

export default class AppWorker extends WorkerEntrypoint {
	async fetch() {
		return new Response(null, { status: 404 });
	}

	// Each method runs near your database - multiple queries stay fast
	async getUser(userId: string) {
		const user = await this.env.DB.prepare("SELECT * FROM users WHERE id = ?")
			.bind(userId)
			.first();
		return user;
	}

	async getUserListings(userId: string) {
		// Multiple round-trips to the DB are low-latency when placed nearby
		const user = await this.env.DB.prepare("SELECT * FROM users WHERE id = ?")
			.bind(userId)
			.first();
		const listings = await this.env.DB.prepare(
			"SELECT * FROM listings WHERE owner_id = ?",
		)
			.bind(userId)
			.all();
		const reviews = await this.env.DB.prepare(
			"SELECT * FROM reviews WHERE listing_id IN (SELECT id FROM listings WHERE owner_id = ?)",
		)
			.bind(userId)
			.all();

		return { user, listings: listings.results, reviews: reviews.results };
	}
}

auth-worker 在边缘运行,可快速拒绝未授权请求。已授权的请求通过 RPC 转发到 app-worker,后者在数据库附近运行以实现快速查询。

Durable Objects

Durable Objects 无需配置即可提供自动放置。对 Durable Object 内嵌 SQLite 数据库 的查询实际上是零延迟的,因为计算与数据运行在同一进程中。

尽可能在 Durable Object 内完成工作并返回组合结果,而不是从 Worker 发起多次往返:

src/index.tsts
import { DurableObject } from "cloudflare:workers";

type Session = { id: string; user_id: string; created_at: number };
type PromptHistory = {
	id: string;
	session_id: string;
	role: string;
	content: string;
};

export class AgentHistory extends DurableObject {
	async getSessionContext(sessionId: string) {
		// All queries execute with zero network latency — compute and data are colocated
		const session = this.ctx.storage.sql
			.exec<Session>("SELECT * FROM sessions WHERE id = ?", sessionId)
			.one();
		const prompts = this.ctx.storage.sql
			.exec<PromptHistory>(
				"SELECT * FROM prompt_history WHERE session_id = ? ORDER BY created_at",
				sessionId,
			)
			.toArray();

		return { session, prompts };
	}
}

这篇文档对您有帮助吗?