← Cloudflare Workers / workers / configuration
Placement
По умолчанию Workers и Pages 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"Placement снижает общую задержку запроса к Worker за счёт минимизации задержки прохождения запросов между вашим Worker и бэкенд-сервисами. Это позволяет добиться задержки на уровне единиц миллисекунд при обращении к базам данных, API и другим сервисам, работающим в устаревшей облачной инфраструктуре.
| Опция | Подходит для | Конфигурация |
|---|---|---|
| Smart | Несколько бэкенд-сервисов или неизвестное расположение инфраструктуры | mode = "smart" |
| Регион | Единый бэкенд-сервис в известном облачном регионе | region |
| Host | Единый бэкенд-сервис вне крупного облачного провайдера | host или hostname |
Изучите размещение
Представим пользователя из Сиднея (Австралия), который обращается к приложению, работающему на Workers. Это приложение выполняет несколько циклов обмена данными с базой данных во Франкфурте (Германия).
Задержка от нескольких обращений туда и обратно между Сиднеем и Франкфуртом накапливается. Если разместить Worker рядом с базой данных, Cloudflare сокращает общую длительность запроса.
Включите Smart Placement
Smart Placement автоматически анализирует характер трафика вашего Worker и размещает его в оптимальном местоположении. Используйте Smart Placement, если:
- Worker подключается к нескольким бэкенд-сервисам
- Вы не знаете точное расположение своей инфраструктуры
- Ваши бэкенд-сервисы распределены или реплицированы
Smart Placement включается для каждого Worker отдельно. После включения он анализирует длительность запроса Worker в разных точках присутствия Cloudflare на регулярной основе.
Для каждой возможной локации Smart Placement учитывает производительность Worker и сетевую задержку, добавляемую при пересылке запроса. Если какая-то локация оказывается значительно быстрее, запрос перенаправляется туда. В остальных случаях Worker выполняется в локации по умолчанию, ближайшей к запросу.
Smart Placement учитывает только те местоположения, где Worker уже выполнялся ранее. Он не может разместить ваш Worker там, куда обычно не поступает трафик.
Ознакомьтесь с ограничениями
- Smart Placement влияет только на выполнение обработчики событий fetch. Это не влияет на Методы RPC или именованные точки входа.
- Workers без обработчика события fetch игнорируются Smart Placement.
- Static Assets всегда отдаются из точки, ближайшей к входящему запросу. Если ваш код получает ресурсы через привязка статических ресурсов, ресурсы отдаются из того места, где выполняется ваш Worker.
Включить Smart Placement
Smart Placement доступен на всех тарифах Workers.
Настройка с помощью Wrangler
Добавьте следующее в файл конфигурации Wrangler:
{
"placement": {
"mode": "smart",
},
}[placement]
mode = "smart"Smart Placement может анализировать ваш Worker до 15 минут после развёртывания.
Настройка в панели управления
-
Перейдите в Workers & Pages.
Перейдите в Workers & Pages ↗ -
Выберите свой Worker.
-
Перейдите в Настройки > Общее.
-
В разделе Placement, выберите Smart.
Для принятия решения о размещении Smart Placement требуется стабильный трафик к Worker из нескольких местоположений. Анализ может занимать до 15 минут.
Проверка статуса размещения
Запросите статус размещения вашего Worker через Workers API:
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% Workers). |
Просмотрите аналитику длительности запросов
После включения 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, задайте placement.region свойство, используя формат {provider}:{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-адресов, а не из диапазонов IP-адресов Cloudflare. Cloudflare регулярно перепроверяет расположение службы. Эти зонды предназначены для ресурсов с одним расположением и не работают корректно для широковещательных, anycast, многоадресных и реплицированных ресурсов.
Список поддерживаемых регионов
Placement Hints поддерживают идентификаторы регионов Amazon Web Services (AWS), Google Cloud Platform (GCP) и Microsoft Azure:
| Провайдер | Формат | Примеры |
|---|---|---|
| AWS | aws:{region} |
aws:us-east-1, aws:us-west-2, aws:eu-central-1 |
| GCP | gcp:{region} |
gcp:us-east4, gcp:europe-west1, gcp:asia-east1 |
| Azure | azure:{region} |
azure:westeurope, azure:eastus, azure:southeastasia |
Полный список кодов регионов см. в Регионы AWS ↗, Регионы GCP ↗, или Регионы Azure ↗.
Placement Behavior
Размещение Workers ведёт себя одинаково при использовании Smart Placement или Placement Hints. Ниже описано поведение, общее для обоих вариантов.
Ознакомьтесь с ограничениями
Следующие ограничения действуют как для Smart Placement, так и для Placement Hints:
- Placement влияет только на выполнение обработчики событий fetch. Это не влияет на Методы RPC или именованные точки входа.
- Workers без обработчика события fetch игнорируются при размещении.
- Static Assets всегда отдаются из точки, ближайшей к входящему запросу. Если ваш код получает ресурсы через привязка статических ресурсов, ресурсы отдаются из того места, где выполняется ваш Worker.
cf-placement заголовок
Cloudflare добавляет cf-placement заголовок добавляется ко всем запросам, если включено размещение. Используйте этот заголовок, чтобы проверить, был ли запрос направлен с учётом размещения и где Worker обработал этот запрос.
Значение заголовка включает тип размещения и код аэропорта, указывающий на расположение дата-центра:
remote-LHR: запрос был маршрутизирован с помощью Smart Placement в дата-центр рядом с Лондоном.local-EWR: запрос не был маршрутизирован с помощью Smart Placement. Worker выполнялся в расположении по умолчанию рядом с Ньюарком.
Несколько Workers
Если вы создаете full-stack приложения на Workers, разделяйте edge-логику (аутентификация, маршрутизация) и логику бэкенда (запросы к базе данных, вызовы API) на отдельные Workers. Используйте Service Bindings чтобы соединить их через типобезопасный RPC.
Включите размещение бэкенд-Worker, чтобы вызывать его ближе к базе данных, а edge Worker будет обрабатывать аутентификацию ближе к пользователю.
Пример: аутентификация на edge с размещённым бэкендом
В этом примере показаны два Worker:
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"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"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:
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 };
}
}