nginx 想针对不同 API 限制不同请求频次应该怎么写?

2022-02-01 10:02:03 +08:00
 LeeReamond

配置方式:前后分离,nginx 分发静态文件,然后将 /api/路由反向代理到后端,前端无跨域。

需求:后端 api 很多,想要使用 nginx 的限频功能,但是不同 api 频率不一样。

现在的写法

#上文省略
location ^~ /api/ {

    proxy_pass http://127.0.0.1:3333;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      
    limit_req zone=allips burst=20 nodelay;
}

现在的写法就是全路由统一反向代理,然后公用一个 limit_req ,比如如果有/api/a1?=.../api/b2?=...这两个 api ,是否 nginx 上需要分别设置各自的路由,各自的反向代理,和各自的 limit_req 的 zone ?如果 api 特别多的话是不是 zone 增多会导致内存爆炸啊。。

3438 次点击
所在节点    NGINX
12 条回复
des
2022-02-01 10:09:25 +08:00
用 map 应该可以
ilylx2008
2022-02-01 11:31:23 +08:00
来个中间件
gstqc
2022-02-01 11:47:12 +08:00
规则不多就多搞几个 location 和 zone
zone 的计数器占不了多少内存
LeeReamond
2022-02-01 11:54:39 +08:00
@gstqc 规则比较多,复写能工作但我感觉这好像不是正确的配置方式。另外一个问题是使用 limit_req 功能是不是就不能使用 cf 代理了
allenforrest
2022-02-01 12:58:28 +08:00
类似这样?

limit_req_zone $request_uri zone=addr2:50m rate=10r/s;
limit_req zone=addr2 burst=20 nodelay;
limit_req_status 503;
adoal
2022-02-01 12:59:43 +08:00
靠纯 nginx 的配置可以做到,不过麻烦,不如上一个 API 网关,kong 或者 apisix
learningman
2022-02-01 13:08:41 +08:00
location 块可以重复生效的吧,limit 写在具体的 block 里行不
ryd994
2022-02-01 13:19:19 +08:00
5 楼的思路是对的。但是第一行忘了加入$binary_remote_addr ,结果就是整个 url 不论 IP 加在一起限速。也没有拆分前缀,往 uri 加额外字符就可以绕过了。要用的话你可以在 location 里用 regex match 然后用 named capture ,捕捉 url 的第一小节。

cf 代理可以用,cf 会设置 x-forwarded-for 和 client-ip ,用好 ngx_http_realip_module ,只信任来自 cloudflare 的 client ip 即可。
ryd994
2022-02-01 13:22:11 +08:00
还有,如果 API 不多的话可以用嵌套 location 。这样就不应反复写代理配置,每个 location 里再写一遍 limit 即可。

还有,你这 location 写的什么玩意?/api/这不就是固定匹配,用什么 regex ?(当然你按我上面说的话那还是得用 regex 去捕捉 api 名称)
wellsc
2022-02-01 13:33:52 +08:00
ng 受限于单点,上 openresty lua redis 吧
ManjusakaL
2022-02-01 14:35:46 +08:00
直接上个 openresty 系列的网关吧
youyoumarco
2022-02-03 13:16:33 +08:00
apisix 走起

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/831569

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX