Nginx 를 사용해서 과도한 요청을 제한시키며, 특정 api 에서 http request method 마다 다른 제한 값을 설정해야하는 상황이 있었다.
다만 $request_method 를 사용해서 if 문 에 limit_req 를 사용하면 오류가 난다.
location /api/ {
if ($request_method = GET) {
limit_req zone=api burst=20 nodelay;
}
# ...
}
위와 같은 코드는 작동하지 않는다.
우선 Github Copilot (Claude 4) 에게 물어봤지만, 비슷한 오류가 나거나 내가 바라는 동작과는 거리가 멀었다.
하지만... Stack Overflow 에서 빛과 같은 게시물을 볼 수 있었다.
Nginx Rate limit GET of POST requests only at a location
http {
... # your nginx.conf here
# Maps ip address to $limit variable if request is of type POST
map $request_method $limit {
default "";
POST $binary_remote_addr;
}
# Creates 10mb zone in memory for storing binary ips
limit_req_zone $limit zone=my_zone:10m rate=1r/s;
}
**Rate limiting for the entire NGINX process:**
http {
... # your nginx.conf here
limit_req zone=global_zone;
}
Nginx 의 map 을 통해 $request_method 마다 필터링을 해서 request method 마다 limit_req 를 설정하는 것을 구현한 답이였다.
나는 위 방법을 따라 아래와 같은 설정으로 사용하였다.
# nginx.conf
http {
map $request_method $limit_post {
default "";
POST $binary_remote_addr;
}
map $request_method $limit_get {
default "";
GET $binary_remote_addr;
}
map $request_method $limit_put {
default "";
PUT $binary_remote_addr;
PATCH $binary_remote_addr;
}
map $request_method $limit_delete {
default "";
DELETE $binary_remote_addr;
}
limit_req_zone $limit_get zone=get_only:10m rate=60r/s;
limit_req_zone $limit_post zone=post_only:10m rate=10r/s;
limit_req_zone $limit_put zone=put_only:10m rate=5r/s;
limit_req_zone $limit_delete zone=delete_only:10m rate=3r/s;
# ...
}
# app.conf
server {
location ~ "/post/[^/]/(like|comments)$" {
limit_req zone=get_only burst=20 nodelay;
limit_req zone=post_only burst=5 nodelay;
limit_req zone=put_only burst=2 nodelay;
limit_req zone=delete_only burst=1 nodelay;
# ...
}
}
비록 Nginx 에서 if 에 limit_req 의 사용이 불가능하지만, 위와 같은 방법으로 GET, POST, PUT, PATCH, DELETE 마다 요청을 제한시킬 수 있었다.