使用 Workers KV 存储路由数据,以通过 Workers 将请求路由到各种 Web 服务器,是 Workers KV 的理想使用场景。路由工作负载可能具有高读取量,Workers KV 的低延迟读取有助于确保路由决策快速高效地进行。
路由有助于根据请求的路径、主机名或其他请求属性,将进入单个 Cloudflare Worker 应用的请求路由到不同的 Web 服务器。
在单租户应用中,这可用于根据业务域将请求路由到各种源服务器(例如,对 /admin 的请求路由到管理服务器,对 /store 的请求路由到店面服务器,对 /api 的请求路由到 API 服务器)。
在多租户应用中,请求可以路由到各租户相应的源资源(例如,对 tenantA.your-worker-hostname.com 的请求路由到租户 A 的服务器,对 tenantB.your-worker-hostname.com 的请求路由到租户 B 的服务器)。
路由还可用于为你自己的外部应用实现 A/B 测试、金丝雀部署或蓝绿部署 ↗。 如果你希望为完全基于 Cloudflare Workers 构建的应用实现金丝雀或蓝绿部署,请参阅 Workers 渐进式部署。
在本示例中,多租户电子商务应用构建在 Cloudflare Workers 上。每个店面是不同的租户,有自己的外部 Web 服务器。 我们的 Cloudflare Worker 负责接收所有店面的所有请求,并根据店面 ID 将请求路由到正确的源 Web 服务器。
为简化演示,店面将通过包含店面 ID 的路径元素来标识,其中
https://<WORKER_HOSTNAME>/<STOREFRONT_ID>/... 是店面的 URL 模式。在真实场景中,你可能更喜欢使用子域名来标识店面。
// Example routing data stored in Workers KV:
// Key: "storefrontA" | Value: {"origin": "https://storefrontA-server.example.com"}
// Key: "storefrontB" | Value: {"origin": "https://storefrontB-server.example.com"}
interface Env {
ROUTING_CONFIG: KVNamespace;
}
export default {
async fetch(request, env, ctx) {
// Parse the URL to extract the storefront ID from the path
const url = new URL(request.url);
const pathParts = url.pathname.split('/').filter(part => part !== '');
// Check if a storefront ID is provided in the path, otherwise return 400
if (pathParts.length === 0) {
return new Response('Welcome to our multi-tenant platform. Please specify a storefront ID in the URL path.', {
status: 400,
headers: { 'Content-Type': 'text/plain' }
});
}
// Extract the storefront ID from the first path segment
const storefrontId = pathParts[0];
try {
// Look up the storefront configuration in KV using env.ROUTING_CONFIG
const storefrontConfig = await env.ROUTING_CONFIG.get<{
origin: string;
}>(storefrontId, {type: "json"});
// If no configuration is found, return a 404
if (!storefrontConfig) {
return new Response(`Storefront "${storefrontId}" not found.`, {
status: 404,
headers: { 'Content-Type': 'text/plain' }
});
}
// Construct the new URL for the origin server
// Remove the storefront ID from the path when forwarding
const newPathname = '/' + pathParts.slice(1).join('/');
const originUrl = new URL(newPathname, storefrontConfig.origin);
originUrl.search = url.search;
// Create a new request to the origin server
const originRequest = new Request(originUrl, {
method: request.method,
headers: request.headers,
body: request.body,
redirect: 'follow'
});
// Send the request to the origin server
const response = await fetch(originRequest);
console.log(response.status)
// Clone the response and add a custom header
const modifiedResponse = new Response(response.body, response);
modifiedResponse.headers.set('X-Served-By', 'Cloudflare Worker');
modifiedResponse.headers.set('X-Storefront-ID', storefrontId);
return modifiedResponse;
} catch (error) {
// Handle any errors
console.error(`Error processing request for storefront ${storefrontId}:`, error);
return new Response('An error occurred while processing your request.', {
status: 500,
headers: { 'Content-Type': 'text/plain' }
});
}
}
} satisfies ExportedHandler<Env>;{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "<ENTER_WORKER_NAME>",
"main": "src/index.ts",
"compatibility_date": "2025-03-03",
"observability": {
"enabled": true
},
"kv_namespaces": [
{
"binding": "ROUTING_CONFIG",
"id": "<YOUR_BINDING_ID>"
}
]
}在本示例中,Cloudflare Worker 接收请求并从 URL 路径中提取店面 ID。
店面 ID 用于通过 get() 方法从 Workers KV 查找源服务器 URL。
然后将请求转发到源服务器,并在返回给客户端之前修改响应以包含自定义标头。