DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

Nginx auth_request_set 已有值,limit_req 的 map 键为何仍为空

认证子请求返回档位晚于limit_req执行,解释map空键、首次求值缓存及日志与限流阶段差异。

认证接口返回用户档位,auth_request_set 把响应头保存到 $tier,再用 map 选择不同的 limit_req_zone。访问日志里 $tier 有值,限流键却为空时,需要先检查这个值在限流执行时是否已经存在。

Nginx 的普通 limit_req 在 PREACCESS 阶段执行,auth_request 在后面的 ACCESS 阶段发起认证子请求。认证完成后才能取得的身份或档位,不能直接作为前一阶段已经需要使用的限流输入。配置文件里把 auth_request 写在上面,不会改变这些执行阶段。

日志中的最终值,不能代表限流时的值

下面的片段展示问题结构,不是可直接上线的分档限流配置:

# http 上下文
map $tier $tier_key {
    default "";
    basic $server_name;
}
limit_req_zone $tier_key zone=basic_tier:10m rate=10r/s;

# 已有 location 内
auth_request /auth;
auth_request_set $tier $upstream_http_tier;
limit_req zone=basic_tier burst=10 nodelay;

限流第一次读取 $tier_key 时,认证子请求尚未完成,map 可能得到空值并缓存结果。随后认证返回 basic,访问日志在更晚阶段记录出有值的 $tier,不等于当时计算限流键也使用了它。

去掉 limit_req 后,map 可能直到写访问日志时才首次求值,看起来就“恢复正常”。这只改变了求值时机,不能证明把同一套配置加回去就能分档限流。

示例还以 $server_name 为档位内的共享键,并非每用户键。即便值能及时获得,同一站点的该档位请求也会共享额度;键设计与值产生时间是两个需要分别确认的问题。

空键跳过计数,与 dry_run 不同

limit_req_zone 的键为空时,该区不会计入这条请求。检查每个实际生效的区及其键,不能只看到请求成功就认定限流允许通过。多个区同时存在时,其中一个空键也不代表其他区都未参与。

limit_req_dry_run on 则仍计算请求速率和超额情况,只是不实施延迟或拒绝。它从 Nginx 1.17.1 起提供;$limit_req_status 从 1.17.6 起可以记录 PASSED、DELAYED、REJECTED 及 dry-run 状态。

空的 $limit_req_status 不能当作 PASSED。应结合加载的配置、区名称、错误日志和实际请求路径判断;日志显示的是请求结束时的数据,必要时用受控诊断确认早期求值。调试日志也可能包含敏感请求内容,应控制范围和持续时间。

volatile 不会让认证结果提前出现

map 的 volatile 从 1.11.7 起让结果不缓存,可以影响后续重新求值。然而 PREACCESS 阶段仍在认证之前,重新求值也拿不到尚未返回的档位。

因此,增加 volatile、给变量改名或调整指令的文本顺序,都不能作为这条路径的完整修复。它们可能改变最终日志,却没有让限流获得可靠身份。

在身份可用的阶段实施所需策略

若要求按认证后的用户或套餐额度限流,选择能在身份验证完成后执行策略的应用或网关层,并保留原来的授权检查。不要直接相信访客传来的 Tier、用户 ID 或任意转发头。

若只需要对入口做粗粒度保护,可以在 PREACCESS 使用当时已可获得、且经过适当可信代理处理的键,例如按实际部署判断的客户端地址。这与认证后的每用户配额不同;多个用户共用地址时会共享限制,应按业务需求评估。

重构请求路径或使用内部跳转前,必须验证认证是否仍然执行、身份能否伪造,以及是否产生循环或重复计数。没有一段通用内部跳转片段能保证适合现有站点。

验证实际额度,而不只验证变量

保存原配置、各限流区与档位策略,先在受控环境核对不同档位、不同身份和未认证请求。记录最终策略使用的键、计数位置、实际拒绝状态以及原认证行为。

验收应说明“哪一类请求共享哪个额度、超额后在哪里被处理”。仅让日志中的 $tier_key 不再为空,仍不足以证明额度隔离和限制生效。若策略不符合预期,恢复本次限流调整并保留诊断记录,不要通过取消认证取得看似正常的结果。