跳转到内容
搜索文档

将请求路由到各种 Web 服务器

在 Workers KV 中存储路由数据,使用 Workers 将请求路由到各种 Web 服务器

最后更新 查看 MarkdownAgent 设置

使用 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 渐进式部署

使用 Workers KV 路由请求

在本示例中,多租户电子商务应用构建在 Cloudflare Workers 上。每个店面是不同的租户,有自己的外部 Web 服务器。 我们的 Cloudflare Worker 负责接收所有店面的所有请求,并根据店面 ID 将请求路由到正确的源 Web 服务器。

为简化演示,店面将通过包含店面 ID 的路径元素来标识,其中 https://<WORKER_HOSTNAME>/<STOREFRONT_ID>/... 是店面的 URL 模式。在真实场景中,你可能更喜欢使用子域名来标识店面。

index.tsjs

// 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。 然后将请求转发到源服务器,并在返回给客户端之前修改响应以包含自定义标头。

相关资源

这篇文档对您有帮助吗?