跳到主要内容
版本:3.10.x

使用调试会话捕获请求链路

指标可以告诉你错误率上升了,访问日志可以告诉你请求匹配了哪个路由和上游,但两者都无法说明网关对失败请求实际执行了哪些操作。

调试会话可以回答这个问题。你可以选择实例、时间窗口和关注的流量。对于每个匹配的请求,网关会记录所有已执行的插件、执行顺序、各插件耗时以及产生的每一行日志。

可以排查哪些问题

哪个插件导致请求变慢。 某个结算端点耗时 400 ms,但你无法判断时间花在了哪里。链路会先按阶段、再按各个插件调用拆分请求,并显示每个调用的耗时,因此可以快速定位慢插件。

插件为什么没有生效。 插件执行顺序根据优先级计算,并合并路由、服务和全局规则上的配置。仅通过阅读配置推导执行顺序容易出错。链路会显示真实请求中实际执行的插件及网关的执行顺序,无需自行推导。

网关为某个特定请求记录了哪些日志。 该请求产生的日志行会附加到其链路中。你无需再提高生产环境的日志级别,也无需从大量输出中筛选属于同一请求的日志。

告警触发时发生了什么。 告警策略可以自动启动会话,在触发告警的流量发生时立即捕获,而不必在事后尝试复现间歇性故障。

工作原理

你可以针对某个网关组创建会话。控制面会将会话下发到所选实例,租约时长等于会话持续时间,因此时间窗口结束时会自动停止捕获。

每个匹配的请求都会记录为 OpenTelemetry 链路。数据面通过现有的心跳认证通道将数据发送到控制面。控制面把数据存储在你自己的 Jaeger 部署中,因此链路数据不会离开你的网络。

备注

调试会话仅追踪 HTTP 流量,不追踪 Stream(L4)代理和 TLS 握手。

前置条件

  • 一个至少包含一个在线实例的网关组,实例运行 API7 网关 3.9.13 或更高版本。
  • 控制面已配置 Jaeger。Helm Chart 和 Docker Compose 部署默认包含 Jaeger。对于 RPM 安装,请自行部署 Jaeger,并在控制台和 DP Manager 配置中设置 jaeger.addrjaeger.collector_addr
  • 具有网关组的 gateway:CreateDebugSession 权限。

无需启用 opentelemetry 插件或静态 apisix.tracing 选项。调试会话使用独立的运行时开关。

步骤 1:启动会话

  1. 前往 Gateway Groups,选择网关组,然后单击 Debug Sessions

  2. 单击 Create Debug Session

  3. 填写表单:

    字段说明
    Name会话标识符,最多 100 个字符。
    Description可选,用于说明启动会话的原因。
    Target Instances要追踪的实例,至少需要选择一个。
    Duration (seconds)实例保持追踪的时长,范围为 10 到 600 秒,默认值为 60。
    Max Samples会话列出的链路数量,范围为 1 到 200,默认值为 5。
    Sampling Rule要捕获的请求。留空将捕获所有请求。
  4. 单击 Submit。会话页面会显示剩余捕获时间的倒计时,链路到达后将出现在列表中。

步骤 2:仅捕获关注的流量

在繁忙的网关上,捕获所有流量会淹没你正在查找的请求。采样规则可以把捕获范围缩小到相关流量。

规则在响应完成后求值,因此不仅可以按传入请求筛选,还可以按状态码、上游延迟等处理结果筛选。

仅筛选服务器错误:

[["status", ">=", 500]]

筛选某个端点的慢请求:

[["uri", "==", "/checkout"], ["upstream_response_time", ">", 1]]

筛选一个租户,匹配地址范围或请求头:

["OR", ["remote_addr", "ipmatch", "10.1.0.0/16"], ["http_x_tenant_id", "==", "acme"]]

规则由 [variable, operator, value] 条件组成。除非第一个元素是 ORAND!OR!AND,否则条件默认以 AND 组合。

常用变量说明
urirequest_urimethodstatus路径、包含查询字符串的路径、方法和响应状态
hostremote_addr请求主机和客户端地址
route_idroute_nameservice_idservice_name匹配的资源
consumer_nameconsumer_group_id已通过身份认证的消费者
upstream_statusupstream_response_time上游结果和耗时
http_<header>arg_<name>cookie_<name>请求头、查询参数或 Cookie

支持的运算符包括 ==~=>>=<<=、用于正则表达式的 ~~~*,以及 inhasipmatch

警告

urimethodstatus 分别表示请求路径、方法和响应状态。不要写成 http_urihttp_methodhttp_status,因为 http_ 前缀表示读取同名请求头,这些表达式永远不会匹配,且会导致会话不提示错误便无法捕获任何内容。

控制台的 Match URIMatch Method5xx Errors 预设按钮目前会插入带 http_ 前缀的形式。单击预设后,请编辑变量名。

步骤 3:读取链路

打开链路,以瀑布图形式查看请求。自上而下读取即可直接看到执行顺序:

GET /checkout 412ms
├─ apisix.phase.access 380ms
│ ├─ http_router_match 0.16ms
│ ├─ apisix.phase.rewrite.plugins.key-auth 3.1ms
│ ├─ apisix.phase.rewrite.plugins.proxy-rewrite 0.4ms
│ └─ apisix.phase.access.plugins.limit-count 371ms ←
├─ apisix.phase.header_filter 0.25ms
└─ apisix.phase.body_filter 1.4ms

每次插件调用都是一个独立的 Span,名称为 apisix.phase.<phase>.plugins.<plugin>,并嵌套在调用插件时处于打开状态的阶段 Span 下。同一阶段内,插件按优先级降序执行,链路也按此顺序显示。在本例中,limit-count 几乎占用了整个请求的耗时。

网关会为 accessheader_filterbody_filter 打开阶段 Span。因此,包括 rewrite 阶段插件在内的请求侧插件都会显示在 apisix.phase.access 下。你还会看到用于路由匹配的 http_router_match、用于全局规则的 run_global_rules.<phase>,以及执行时出现的 resolve_dnsfetch_secret

请求自身的日志

选择根 Span 并打开 Events 选项卡,可以查看该请求产生的日志行,包括日志级别、源位置和消息。

捕获过程不受网关所配置 error_log 级别的影响。因此,即使某条 debug 级消息从未写入错误日志,也会显示在这里。每个请求最多保留 200 条日志,每条最多 2048 字节。nginx 自身写入的日志行(例如上游连接错误)不会被捕获;以 Lua 表形式记录的结构化参数会显示为 {...}

备注

将日志作为 Span 事件捕获需要 API7 网关 3.9.15、3.10.2 或更高版本。

导出链路

单击 Download OTLP JSON,可以将链路导出为 OpenTelemetry 文档,便于附加到支持工单或离线分析。

告警触发时自动捕获

间歇性故障很难手动捕获:当有人看到告警并启动会话时,触发告警的请求通常早已结束。你可以改为让告警自动启动会话。

  1. 前往 Alerts,打开告警策略,然后找到 Debug Sessions 部分。
  2. 添加配置,设置持续时间、最大样本数和可选的采样规则。

策略触发时,控制面会针对满足条件的每个网关组,为每项配置创建一个会话,并以组中的所有实例为目标。告警历史记录会保存该会话,你可以直接从告警详情打开。

如果同一策略在该网关组上创建的会话仍处于活动状态,则不会创建新会话。因此,反复触发和恢复的告警只会产生一个捕获窗口,不会创建数百个会话;活动会话的持续时间相当于冷却时间。

在生产环境运行会话前

链路记录的是真实流量,请先了解其中会保存哪些内容。

会捕获:包含查询字符串的完整请求 URL;请求主机、方法和响应状态;User-Agent 请求头;路由、服务和实例标识符;插件和阶段名称及其耗时;请求自身的日志行。

不会捕获:请求体、响应体,以及 HostUser-Agent 以外的任何请求头或响应头。

注意

链路内容按原样存储,不会脱敏。如果 URL 的查询字符串包含敏感值,或插件记录了敏感值,这些数据会出现在链路和导出文件中。请优先使用精确的采样规则,而不是捕获所有流量,并限制 gateway:GetDebugSessiongateway:ExportDebugSession 权限。

限制和行为

属性
会话持续时间10 到 600 秒
最大样本数1 到 200。仅限制会话列出的链路数量,不限制实际捕获数量。在整个持续时间内,所有匹配规则的请求都会被捕获。
流量范围仅 HTTP
并发会话不限制
链路保留时间由 Jaeger 部署的保留策略决定

每个请求最多由一个会话捕获。有采样规则的会话优先于没有采样规则的会话;其他条件相同时,选择结果不确定。如果多人同时调试同一个网关组,请为每个会话设置采样规则。

停止会话会保留已经收集的链路。删除会话会从控制面移除会话及其链路列表,但 Span 数据会一直保留在 Jaeger 中,直到保留策略到期。若要删除捕获内容,请使用 Jaeger 部署自身的控制功能。

相关内容

  • 配置分布式追踪:将持续采样的链路发送到自己的收集器,用于日常可观测性。
  • 配置告警:可自动启动调试会话的告警策略。