使用Cloudflare Worker作为AWS Lambda反向代理时延迟过高的原因及优化方案咨询
这种延迟确实远超预期,我来帮你拆解可能的原因,再给出对应的优化思路和具体调整方案:
一、先定位问题根源:到底慢在哪里?
首先得明确延迟是出在Worker本身的处理,还是从Cloudflare节点到Lambda的网络路径上。你可以先给Worker代码加几个日志,精准排查耗时点:
- 记录Worker运行的Cloudflare节点:确认Worker是不是在离你最近的边缘节点执行(比如巴西的萨尔瓦多SSA或圣保罗GRU节点)
- 记录fetch请求的耗时:看从Worker发起请求到拿到Lambda响应的时间到底有多长
修改后的代码片段(关键部分):
export default { async fetch(request: Request) { // 打印Worker所在的Cloudflare节点代码 console.log(`Worker running in colo: ${request.cf?.colo}`); // ... 省略OPTIONS处理代码 ... const fetchStart = Date.now(); const data = await fetch(url.toString(), { method: request.method, headers, body: request.body, }); // 打印fetch到Lambda的耗时 console.log(`Fetch to Lambda took ${Date.now() - fetchStart}ms`); // ... 省略后续处理代码 ... }, };
通过Cloudflare Dashboard的Worker日志查看这些信息:
- 如果
Worker running in colo显示的是离巴西很远的节点(比如美国的IAD、ORD),那问题出在Worker的调度区域,导致网络绕路 - 如果
Fetch to Lambda took显示耗时2s左右,那核心问题是Cloudflare节点到Lambda的网络路径拥堵或绕路 - 如果fetch耗时正常(几百ms),那才需要排查Worker的代码逻辑开销(但你的代码逻辑非常简单,这种概率极低)
二、针对不同根源的优化方案
1. 如果Worker调度到了远节点
Cloudflare Worker默认会选择离请求发起者最近的边缘节点,但偶尔可能因为路由策略、节点负载等问题调度到远节点。你可以:
- 检查你的域名是否正确配置了Cloudflare的橙色云朵(代理模式),确保请求经过Cloudflare的边缘网络
- 尝试使用Cloudflare的Regional Workers(如果你的套餐支持),强制Worker只在巴西区域的节点运行,避免跨区域调度
2. 如果Cloudflare到Lambda的网络路径慢
这是最可能的原因,毕竟你的Lambda在us-east-1(美国东部),而你在巴西,跨大西洋的网络本身就有延迟,再加上路径绕路或拥堵,就会放大延迟。优化思路:
(1)优化Worker的fetch请求参数
给fetch添加cf配置项,让Cloudflare优化网络路径和协议:
const data = await fetch(url.toString(), { method: request.method, headers, body: request.body, cf: { httpVersion: "h2", // 强制使用HTTP/2,减少TCP连接开销 cacheTtl: 0, // 禁用Cloudflare对Lambda响应的缓存(如果是动态请求) tcpKeepalive: true, // 启用TCP长连接复用,减少后续请求的连接建立时间 }, });
(2)把Lambda迁移到离你更近的AWS区域
AWS在巴西有sa-east-1(圣保罗)区域,把Lambda部署到这里后,从巴西的Cloudflare节点到Lambda的网络延迟会从几百ms降到几十ms,整体延迟会直接砍半甚至更多。这是最有效的长期优化方案。
(3)给Lambda URL绑定自定义域名并通过Cloudflare代理
把Lambda URL绑定到一个自定义域名,然后在Cloudflare DNS里设置该域名的CNAME记录指向Lambda URL,开启橙色云朵代理。这样Cloudflare会优化从边缘节点到Lambda的请求路径,甚至可能通过内部骨干网络转发,减少绕路。
3. 其他可能的隐藏因素
- Cloudflare附加功能的开销:如果你的域名开启了WAF、Bot Management、Rate Limiting等功能,这些会增加请求处理时间。可以暂时禁用这些功能测试,如果延迟下降,再调整规则(比如给你的请求添加白名单,跳过不必要的检查)
- Lambda的冷启动被频繁触发:虽然Lambda的冷启动和请求源无关,但如果Worker转发的请求量极低,AWS可能会频繁回收实例,导致每次请求都触发冷启动。你可以给Lambda配置预留并发,确保始终有暖实例在运行,避免冷启动延迟。
三、短期快速优化(针对你的场景)
因为你的Lambda返回的是固定的"hello world",可以直接在Worker里缓存响应,彻底避免转发到Lambda:
// 在Worker顶部定义缓存键前缀 const CACHE_KEY_PREFIX = "lambda-hello:"; export default { async fetch(request: Request) { // ... 省略OPTIONS处理代码 ... const cacheKey = new Request(request.url, { method: "GET" }); const cache = caches.default; let response = await cache.match(cacheKey); if (!response) { // 缓存未命中时才转发到Lambda const fetchStart = Date.now(); const data = await fetch(url.toString(), { method: request.method, headers, body: request.body, cf: { httpVersion: "h2" } }); console.log(`Fetch to Lambda took ${Date.now() - fetchStart}ms`); response = new Response(data.body, data); addCorsHeaders(response); // 设置缓存1小时 response.headers.set("Cache-Control", "public, max-age=3600"); // 把响应存入缓存(用event.waitUntil确保缓存操作在响应返回后完成) request.waitUntil(cache.put(cacheKey, response.clone())); } return response; }, };
这样第一次请求可能还是有延迟,但后续请求会直接从Cloudflare缓存返回,延迟降到几ms级别。
按照这个思路,先定位问题,再针对性优化,应该能把延迟降到合理范围。




