← Cloudflare for Platforms / cloudflare-for-platforms / workers-for-platforms / configuration
Dynamický dispatch Worker
A dynamic dispatch Worker je specializovaný směrovací Worker, který přesměrovává příchozí požadavky na příslušné uživatelské Workery ve vašem dispatch namespace. Místo použití Trasy Workerů, dispatch Workers vám umožňují programově řídit směrování požadavků pomocí kódu.
Proč používat dynamic dispatch Worker?
- Škálování: Směrujte požadavky pro miliony hostname na různé Workery, aniž byste museli definovat Trasy Workerů konfiguraci pro každý z nich
- Vlastní logika směrování: Napište kód, který přesně určí, jak se mají požadavky směrovat. Například:
- Ukládejte mapování hostitelských názvů na Workery do Workers KV a dynamicky je vyhledávat
- Směrujte požadavky podle subdomény, cesty, hlaviček nebo jiných vlastností požadavku
- Použijte vlastní metadata připojené k vlastní názvy hostitelů pro rozhodování o směrování
- Přidání funkčnosti platformy: Sestavte doplňkové funkce na úrovni směrování:
- Provádějte kontroly ověřování dříve, než požadavky dosáhnou uživatelských Workerů
- Odebírejte nebo přidávejte hlavičky či metadata z příchozích požadavků
- Připojte užitečný kontext, například ID uživatelů nebo informace o účtu
- Transformujte požadavky nebo odpovědi podle potřeby
Nakonfigurujte vazbu dispatch namespace
Aby váš dynamický dispatch Worker mohl dynamicky směrovat požadavky na Workery v namespace, musíte nakonfigurovat dispatch namespace binding. Tento binding umožňuje vašemu dynamic dispatch Workeru volat libovolný user Worker v rámci daného namespace pomocí env.dispatcher.get().
{
"dispatch_namespaces": [
{
"binding": "DISPATCHER",
"namespace": "my-dispatch-namespace"
}
]
}[[dispatch_namespaces]]
binding = "DISPATCHER"
namespace = "my-dispatch-namespace"Jakmile je binding nakonfigurovaný, může váš dynamic dispatch Worker směrovat požadavky na libovolný Worker v namespace. Níže najdete běžné vzory směrování, které můžete ve svém dispatcheru implementovat.
Příklady směrování
Směrování založené na KV
Ukládejte mapování směrování do Workers KV. Díky tomu můžete upravovat logiku směrování, aniž byste museli měnit nebo znovu nasazovat 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 });
}
},
};Směrování založené na subdoméně
Směrujte subdomény na odpovídající Worker. Například my-customer.example.com bude směrováno na Worker s názvem my-customer v dispatch namespace.
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 });
}
},
};Směrování na základě cesty
Směrujte cesty URL na odpovídající Worker. Například example.com/customer-1 bude směrováno na Worker s názvem customer-1 v dispatch namespace.
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 });
}
},
};Vynucujte vlastní limity
Použijte vlastní limity k tomu, abyste omezili, kolik CPU času může daný uživatelský Worker využít nebo kolik subrequestů může vytvořit. Různé limity můžete nastavit podle typu plánu zákazníka nebo podle jiných kritérií.
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 });
}
},
};Další podrobnosti o dostupných limitech najdete v Vlastní limity.
Chcete-li sledovat překročení limitů a další metriky napříč uživatelskými Workery, použijte Workers Analytics Engine. Pro podrobné protokolování a ladění nakonfigurujte Tail Worker k zachycení událostí z vašeho dispatch Workeru.