Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

配置

最終更新 Markdown で表示Agent セットアップ

デフォルトでは、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 主要なクラウドプロバイダー上にない単一のバックエンドサービス host または hostname

配置を理解する

シドニー(オーストラリア)のユーザーが、Workers 上で動くアプリケーションにアクセスする場面を考えます。このアプリケーションは、フランクフルト(ドイツ)のデータベースへ複数回往復します。

シドニー(オーストラリア)のユーザーが同じ地域の Worker に接続し、その Worker がフランクフルト(ドイツ)のデータベースへ複数回往復する様子。

シドニーとフランクフルト間の往復が重なると、レイテンシは積み上がります。Worker をデータベースの近くに置くと、Cloudflare はリクエスト全体の所要時間を短縮できます。

シドニー(オーストラリア)のユーザーがフランクフルト(ドイツ)の Worker に接続し、その Worker が同じくフランクフルト(ドイツ)のデータベースへ複数回往復する様子。

Smart Placement を有効にする

Smart Placement は、Worker のトラフィックパターンを自動分析し、最適な場所に配置します。次の場合に Smart Placement を使います。

  • Worker が複数のバックエンドサービスに接続する
  • インフラの正確な場所が分からない
  • バックエンドサービスが分散または複製されている

Smart Placement は Worker 単位で有効にします。有効化すると、異なる Cloudflare 拠点での Worker の リクエスト所要時間 を定期的に分析します。

各候補拠点について、Smart Placement は Worker の性能と、リクエスト転送で増えるネットワークレイテンシを考慮します。候補拠点が明らかに速い場合は、リクエストをそこに転送します。そうでなければ、リクエストに最も近いデフォルトの拠点で Worker が実行されます。

Smart Placement が検討するのは、その Worker が以前に実行された拠点だけです。通常トラフィックを受け取らない拠点には配置できません。

制限事項を確認する

Smart Placement を有効化する

Smart Placement は、すべての Workers プランで利用できます。

Wrangler で設定する

Wrangler の設定ファイルに次を追加します。

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

デプロイ後、Smart Placement が Worker を分析するまで最大 15 分かかることがあります。

ダッシュボードで設定する

  1. Workers & Pages を開きます。

    Workers & Pages を開く ↗
  2. Worker を選択します。

  3. Settings > General を開きます。

  4. PlacementSmart を選択します。

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 複数拠点からのリクエストが不足しており、配置を決められません。
UNSUPPORTED_APPLICATION Smart Placement によって Worker が遅くなったため、配置を元に戻しました。この状態はまれです(Worker の 1% 未満)。

リクエスト所要時間の分析を確認する

Smart Placement を有効にすると、リクエスト所要時間のデータが収集されます。リクエスト所要時間は、エンドユーザーに最も近いデータセンターで計測されます。比較のベースラインとして、デフォルトではリクエストの 1% は Smart Placement でルーティングされません。

Smart Placement の効果を測るには、Worker の リクエスト所要時間の分析 を確認します。

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 は外部ホストの位置を三角測量し、近くのリージョンに Workers を配置します。

レイヤー 4 のサービスを識別するには placement.host を設定します。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"

レイヤー 7 のサービスを識別するには placement.hostname を設定します。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"

プローブは Cloudflare の IP 範囲ではなく、パブリック 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 はユーザーの近くで認証を処理します。

例: エッジでの認証と配置されたバックエンド

この例では、2 つの 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 へ転送され、app-worker はデータベースの近くで実行されるため、クエリが速くなります。

Durable Objects

Durable Objects は、設定なしで自動配置を提供します。Durable Object に埋め込まれた SQLite データベース へのクエリは、コンピュートがデータと同じプロセスで動くため、実質的に ゼロレイテンシ です。

Worker から複数回往復するのではなく、Durable Object 内でできるだけ多くの処理を行い、合成した結果を返します。

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 };
	}
}

役に立ちましたか?