Cloudflare Traces:把边缘规则、Workers 与源站串成一条请求链路

2026-10-02 19 预计阅读时间: 1 分钟
来源: blog.cloudflare.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

排查一条经过 Cloudflare 的请求,过去往往要在安全事件、缓存状态、Workers 日志和源站日志之间反复切换。Cloudflare Traces 的关键变化,是把请求经过安全规则、转换、缓存、路由、Workers 和源站的过程连接起来,并继续追踪它在其他服务中的流动。对开发团队而言,这比单独增加一份日志更重要:问题开始以“请求链路”而不是“产品页面”为单位呈现。

真正要解决的是跨层归因

一条请求可能在到达业务代码前就被多次处理。出现 403、缓存内容异常、请求头丢失或延迟突增时,仅查看源站通常无法回答这些问题:

  • 请求是否被某条安全规则拦截或改变了处理路径?
  • URL、请求头或其他属性是否经过转换?
  • 返回内容来自缓存、Workers,还是源站?
  • 路由是否把请求送到了预期服务?
  • Workers 执行之后,请求发往了哪个后端?
  • 延迟发生在边缘处理、源站,还是后续微服务中?

Cloudflare Traces 的价值在于将这些阶段放进同一条因果链。它不只是告诉你某个组件“发生过什么”,而是帮助确认前一个组件的决定如何影响后一个组件。

例如,源站没有收到请求,并不一定意味着源站故障。请求可能已在安全层结束,也可能由缓存直接响应。类似地,源站记录的路径与客户端发送的不一致,也可能是转换或 Workers 逻辑造成的。沿着链路观察,可以减少团队之间互相转交问题的时间。

阅读 Trace 时,不要只盯着耗时

调用链工具经常被当作性能瀑布图使用,但端到端排障还要检查请求状态如何变化。可以按下面的顺序阅读一次 Trace:

  1. 确认入口请求:核对方法、主机名、路径、时间范围和用于关联请求的标识。
  2. 检查安全决策:确认请求是否被允许继续,以及规则是否触发了挑战、拦截或其他动作。
  3. 比较转换前后状态:重点关注 URL、查询参数和请求头是否发生变化。
  4. 判断响应来源:区分缓存、Workers 和源站,避免在没有参与响应的系统中浪费时间。
  5. 检查路由与 Workers:确认请求进入了预期代码路径,并被转发到正确的后端。
  6. 继续追踪应用服务:请求离开边缘后,使用统一的关联标识检查网关、API、数据库访问层或异步任务。

这套顺序同时适用于错误和性能问题。对于延迟问题,应比较各阶段耗时;对于正确性问题,则应比较每个阶段前后的请求属性与决策结果。

可以这样实践:给源站日志补上关联 ID

下面是一个可改造的实践方案:在 Worker 中保留已有的 x-request-id,没有时生成一个,然后把它传给源站并写回响应头。这样,即使团队还在逐步接入完整链路追踪,也能用同一个 ID 对照客户端、Worker 和源站日志。

这只是通用的应用层关联方案,不代表 Cloudflare Traces 的内部字段或导出接口。若 Cloudflare Traces 提供了官方追踪上下文,应优先按照产品文档传播该上下文,而不是用自定义 ID 替换它。

创建 src/index.js:

export default {
  async fetch(request, env) {
    const incomingUrl = new URL(request.url);
    const originUrl = new URL(env.ORIGIN_BASE_URL);

    originUrl.pathname = incomingUrl.pathname;
    originUrl.search = incomingUrl.search;

    const headers = new Headers(request.headers);
    const requestId = headers.get("x-request-id") || crypto.randomUUID();
    headers.set("x-request-id", requestId);

    const hasBody = request.method !== "GET" && request.method !== "HEAD";
    const upstreamRequest = new Request(originUrl, {
      method: request.method,
      headers,
      body: hasBody ? request.body : undefined,
      redirect: "manual"
    });

    const upstreamResponse = await fetch(upstreamRequest);
    const responseHeaders = new Headers(upstreamResponse.headers);
    responseHeaders.set("x-request-id", requestId);

    return new Response(upstreamResponse.body, {
      status: upstreamResponse.status,
      statusText: upstreamResponse.statusText,
      headers: responseHeaders
    });
  }
};

对应的 wrangler.toml 可以这样写,运行前将示例域名改为自己的 HTTPS 源站:

name = "trace-correlation-demo"
main = "src/index.js"
compatibility_date = "2025-01-01"

[vars]
ORIGIN_BASE_URL = "https://origin.example.com"

部署并发起测试请求:

npx wrangler deploy

curl -i \
  -H 'x-request-id: checkout-debug-001' \
  'https://your-worker.example.com/api/orders/42'

源站应把这个字段写入结构化日志。下面的 Python 服务只使用标准库,可以直接运行,用于验证请求头是否成功传递:

from http.server import BaseHTTPRequestHandler, HTTPServer
import json


class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        request_id = self.headers.get("x-request-id", "missing")
        print(json.dumps({
            "request_id": request_id,
            "method": self.command,
            "path": self.path
        }))

        body = json.dumps({"ok": True, "request_id": request_id}).encode()
        self.send_response(200)
        self.send_header("content-type", "application/json")
        self.send_header("content-length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)


HTTPServer(("0.0.0.0", 8080), Handler).serve_forever()

本地启动并测试:

python origin.py
curl -i -H 'x-request-id: checkout-debug-001' http://127.0.0.1:8080/api/orders/42

生产环境中不要让客户端提供的任意 ID 直接成为可信安全字段。可以校验长度和字符集,或在边缘生成内部 ID,同时将外部 ID 作为单独字段保留。

一条适合团队执行的排障路径

当用户报告“结账接口偶发超时”时,可以采用下面的流程,而不是同时搜索所有日志:

  • 固定一个可复现请求,记录准确时间、路径和关联 ID。
  • 在 Trace 中确认请求是否经过了预期的安全、转换、缓存和路由阶段。
  • 查看 Workers 是否调用了正确的源站,以及边缘阶段是否已经出现明显延迟。
  • 进入源站和后续服务,用同一个关联 ID 搜索结构化日志。
  • 找到最早出现状态异常或耗时突增的阶段,而不是只处理最后一个报错的组件。
  • 修复后使用相同请求条件回归,比较修改前后的链路。

这种方法的重点是寻找“第一个偏离预期的节点”。下游错误经常只是上游错误的结果,例如错误路由可能最终表现为源站 404,而请求头转换错误可能最终表现为鉴权失败。

接入前需要划清的边界

端到端追踪会提高可观测性,也会带来新的治理要求:

  • 敏感数据:不要默认记录完整 Cookie、Authorization、请求体或个人信息。
  • 采样策略:高流量服务需要在成本与排障精度之间平衡;错误请求和关键交易可以采用更高采样率。
  • 标识传播:跨服务调用、消息队列和后台任务都要明确如何传递追踪上下文。
  • 日志基数:请求 ID 适合检索,但不适合直接作为监控指标标签,否则可能产生高基数问题。
  • 时钟与异步边界:跨区域时钟偏差、重试和队列等待可能让时间线看起来不连续。
  • 访问控制与保留期:Trace 可能暴露内部主机名、路径和规则决策,应限制访问并设置合理保留周期。

采用 Cloudflare Traces 时,可以先选一个同时经过安全规则、Workers 和源站的关键接口进行试点。验证团队能否用一条 Trace 回答“请求在哪里改变、在哪里结束、时间花在哪里”这三个问题,再扩大覆盖范围。工具本身提供的是链路,真正缩短故障时间的,是统一的关联标识、结构化日志和清晰的排障流程。


相关推荐