← Cloudflare for Platforms / cloudflare-for-platforms / workers-for-platforms / configuration
Динамический dispatch Worker
A Worker динамической диспетчеризации это специализированный маршрутизирующий Worker, который направляет входящие запросы к соответствующим пользовательским Workers в вашем пространстве имён диспетчеризации. Вместо использования Маршруты Workers, dispatch Workers позволяют программно управлять маршрутизацией запросов с помощью кода.
Зачем использовать dynamic dispatch Worker?
- Масштабирование: Направляйте запросы для миллионов имён хостов на разные Workers, не определяя Маршруты Workers конфигурацию для каждого из них
- Пользовательская логика маршрутизации: Напишите код, который точно определит, как должны маршрутизироваться запросы. Например:
- Сохраняйте сопоставления имени хоста с Worker в Workers KV и искать их динамически
- Направляйте запросы на основе поддомена, пути, заголовков или других свойств запроса
- Используйте пользовательские метаданные подключённых к пользовательские имена хостов для принятия решений о маршрутизации
- Добавление функциональности платформы: Реализуйте дополнительные функции на уровне маршрутизации:
- Выполняйте проверки аутентификации до того, как запросы достигнут пользовательских Workers
- Удаляйте или добавляйте заголовки и метаданные во входящих запросах
- Добавляйте полезный контекст, например ID пользователей или информацию об аккаунте
- Преобразуйте запросы или ответы по мере необходимости
Настройте привязку dispatch namespace
Чтобы ваш динамический dispatch Worker мог динамически направлять запросы к Workers в пространстве имён, нужно настроить dispatch namespace привязка. Этот binding позволяет вашему dynamic dispatch Worker обращаться к любому user Worker в этом пространстве имён с помощью env.dispatcher.get().
{
"dispatch_namespaces": [
{
"binding": "DISPATCHER",
"namespace": "my-dispatch-namespace"
}
]
}[[dispatch_namespaces]]
binding = "DISPATCHER"
namespace = "my-dispatch-namespace"Как только привязка будет настроена, ваш dynamic dispatch Worker сможет направлять запросы к любому Worker в пространстве имён. Ниже приведены распространённые шаблоны маршрутизации, которые можно реализовать в своём диспетчере.
Примеры маршрутизации
Маршрутизация на основе KV
Сохраняйте сопоставления маршрутизации в Workers KV. Благодаря этому вы можете изменять логику маршрутизации, не меняя и не разворачивая заново dynamic dispatch Worker.
export default {
async fetch(request, env) {
try {
const url = new URL(request.url);
// Use hostname, path, or any combination as the routing key
const routingKey = url.hostname;
// Lookup user Worker name from KV store
const userWorkerName = await env.USER_ROUTING.get(routingKey);
if (!userWorkerName) {
return new Response("Route not configured", { status: 404 });
}
// Optional: Cache the KV lookup result
const userWorker = env.DISPATCHER.get(userWorkerName);
return await userWorker.fetch(request);
} catch (e) {
if (e.message.startsWith("Worker not found")) {
return new Response("", { status: 404 });
}
return new Response(e.message, { status: 500 });
}
},
};Маршрутизация на основе поддоменов
Направляйте поддомены на соответствующий Worker. Например, my-customer.example.com будет направляться на Worker с именем my-customer в пространстве имён диспетчеризации.
export default {
async fetch(request, env) {
try {
// Extract user Worker name from subdomain
// Example: customer1.example.com -> customer1
const url = new URL(request.url);
const userWorkerName = url.hostname.split(".")[0];
// Get user Worker from dispatch namespace
const userWorker = env.DISPATCHER.get(userWorkerName);
return await userWorker.fetch(request);
} catch (e) {
if (e.message.startsWith("Worker not found")) {
// User Worker doesn't exist in dispatch namespace
return new Response("", { status: 404 });
}
// Could be any other exception from fetch() or from the dispatched Worker
return new Response(e.message, { status: 500 });
}
},
};Маршрутизация на основе пути
Направляйте пути URL на соответствующий Worker. Например, example.com/customer-1 будет направляться на Worker с именем customer-1 в пространстве имён диспетчеризации.
export default {
async fetch(request, env) {
try {
const url = new URL(request.url);
const pathParts = url.pathname.split("/").filter(Boolean);
if (pathParts.length === 0) {
return new Response("Invalid path", { status: 400 });
}
// example.com/customer-1 -> routes to 'customer-1' worker
const userWorkerName = pathParts[0];
const userWorker = env.DISPATCHER.get(userWorkerName);
return await userWorker.fetch(request);
} catch (e) {
if (e.message.startsWith("Worker not found")) {
return new Response("", { status: 404 });
}
return new Response(e.message, { status: 500 });
}
},
};Применяйте пользовательские лимиты
Используйте пользовательские лимиты чтобы ограничить, сколько времени CPU может использовать конкретный пользовательский Worker или сколько subrequests он может выполнить. Разные лимиты можно задавать в зависимости от тарифного плана клиента или других критериев.
export default {
async fetch(request, env) {
try {
const url = new URL(request.url);
const userWorkerName = url.hostname.split(".")[0];
// Look up customer plan from your database or KV
const customerPlan = await env.CUSTOMERS.get(userWorkerName);
// Set limits based on plan type
const plans = {
enterprise: { cpuMs: 50, subRequests: 50 },
pro: { cpuMs: 20, subRequests: 20 },
free: { cpuMs: 10, subRequests: 5 },
};
const limits = plans[customerPlan] || plans.free;
const userWorker = env.DISPATCHER.get(userWorkerName, {}, { limits });
return await userWorker.fetch(request);
} catch (e) {
if (e.message.startsWith("Worker not found")) {
return new Response("", { status: 404 });
}
if (e.message.includes("CPU time limit")) {
// Track limit violations with Analytics Engine
env.ANALYTICS.writeDataPoint({
indexes: [userWorkerName],
blobs: ["cpu_limit_exceeded"],
});
return new Response("CPU limit exceeded", { status: 429 });
}
return new Response(e.message, { status: 500 });
}
},
};Дополнительные сведения о доступных лимитах см. в Пользовательские лимиты.
Чтобы отслеживать нарушения лимитов и другие метрики по всем user Workers, используйте Workers Analytics Engine. Для подробного логирования и отладки настройте Tail Worker для сбора событий из вашего dispatch Worker.