Nginx动态限流与访问控制需识别上下文、分离维度、按需响应:通过map提取语义标签、real_ip还原真实IP、多变量识别身份;为不同场景(用户、CDN、API、敏感路径)独立定义limit_req_zone;在location中用if条件启用策略,并结合缓存降级提升弹性。

Nginx 实现基于策略的动态限流与访问控制,核心在于识别上下文、分离控制维度、按需响应。它不是写死一个 rate=5r/s 就完事,而是让限流和访问规则能随请求来源、行为特征、业务等级实时变化。
识别关键上下文,为策略提供判断依据
限流和访问控制的前提是“知道面对的是谁、来自哪里、想干什么”。Nginx 本身不自动分类流量,必须靠配置主动提取特征:
-
用
map提取语义标签:比如根据$http_user_agent判断是否 CDN 回源、是否爬虫、是否内部监控探针; -
用
set_real_ip_from+real_ip_header还原真实客户端或 CDN 节点 IP(尤其启用 CDN 后$remote_addr已被代理覆盖); -
结合
$arg_token、$http_referer、$request_method等变量,识别 API 调用身份、来源域、操作类型。
例如:map $http_user_agent $is_cdn { ~*(alibabacloud-cdn|tencent-cache|cloudflare) 1; default 0; } map $arg_appid $app_tier { "app-prod" high; "app-test" low; default normal; }
按策略维度独立定义限流区域
不同场景应使用不同 limit_req_zone,避免混用导致误伤:
- 对普通用户:按
$binary_remote_addr限流,防刷防爆; - 对 CDN 回源:按
$remote_addr(还原后的真实 CDN 节点 IP)单独限流,阈值更高但需 burst 控制突发; - 对 API 接口:按
$arg_appid或$http_authorization哈希限流,实现租户级配额; - 对敏感路径(如
/login):可叠加按$binary_remote_addr+$request_method复合键限流,防暴力破解。
示例:limit_req_zone $binary_remote_addr zone=user:10m rate=20r/m; limit_req_zone $remote_addr zone=cdn:10m rate=50r/s; limit_req_zone $arg_appid zone=api:10m rate=100r/m;
在 location 中条件化启用策略
用 limit_req ... if= 和 deny/allow 配合变量,实现“该限才限、该放才放”:
只对识别出的 CDN 请求启用 CDN 专属限流;
对高优先级
appid放宽限制,对未授权请求直接return 403;-
对非 GET 请求在管理路径下强制校验 Referer 或 Token。
例如:location /api/ { # 租户级限流,未传 appid 的请求直接拒绝 if ($arg_appid = "") { return 400; } limit_req zone=api burst=30 nodelay if=$arg_appid; # 高优先级租户放宽限制 if ($app_tier = "high") { limit_req zone=api burst=100 nodelay; } proxy_pass http://backend; }
location /static/ {
仅允许来自白名单 Referer 或 CDN 的请求
valid_referers none server_names *.mycompany.com;
if ($invalid_referer && !$is_cdn) { return 403; }}
### 结合缓存与降级提升策略弹性 动态策略不只是“拦”,还要“疏”和“扛”: - 对 CDN 回源请求,配合 `proxy_cache_use_stale error timeout updating`,让 Nginx 在源站慢或挂时仍可返回旧缓存,减少回源压力; - 对高频但低风险请求(如健康检查),用 `limit_req_status 429` 统一返回,再配合前端重试退避逻辑; - 对触发限流的请求,用 `log_format` 记录 `$is_cdn`、`$app_tier`、`$status` 等字段,便于后续分析策略效果。 不复杂但容易忽略。


















