본문 바로가기

서버운영 (TA, ADMIN)/미들웨어

[Nginx] Rate Limiting - ngx_http_limit_req_module

https://nginx.org/en/docs/http/ngx_http_limit_req_module.html

 

`ngx_http_limit_req_module` 모듈(0.7.21)은 정의된 키당 요청 처리 속도를 제한하는데 사용되며, 특히 단일 IP 주소에서 오는 요청의 처리 속도를 제한하는데 사용된다. 이 제한은 "leaky bucket (누수 버킷)" 방법을 사용하여 수행된다.

예제 구성

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    
    ...
    
    server {
        ...
        
        location /search/ {
            limit_req zone=one burst=5;
        }
    }
}

지시문

- 구문: `limit_req zone=name [burst=number] [nodely | delay=number]`
- 기본값: —
- Context: http, server, location

 

공유 메모리 영역과 요청의 최대 버스트 크기를 설정한다. 요청 속도가 영역에 대해 구성된 속도를 초과하면 요청 처리가 지연되어 정의된 속도로 요청이 처리된다. 과도한 요청은 최대 버스트 크기를 초과할 때까지 지연되며, 이 경우 요청은 오류와 함께 종료된다. 기본적으로 최대 버스트 크기는 0이다. 예를 들어, 다음 지시문은 평균적으로 초당 1개의 요청을 허용하며, 버스트는 최대 5개의 요청을 초과하지 않는다.

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server {
    location /search/ {
        limit_req zone=one burst=5;
    }
}

 

과도한 요청을 지연시키지 않으려면 'nodelay' 매개변수를 사용해야 한다.

limit_req zone=one burst=5 nodelay;

 

`delay` 매개변수는 과도한 요청이 지연되는 한계를 지정한다. 기본값은 0이며, 즉 모든 과도한 요청이 지연된다.

 

여러 `limit_req` 지시문이 있을 수 있다. 예를 들어, 다음 구성은 단일 IP 주소에서 오는 요청 처리 속도와 동시에 가상 서버의 요청 처리 속도를 제한한다.

limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
limit_req_zone $server_name zone=perserver:10m rate=10r/s;

server {
    ...
    limit_req zone=perip burst=5 nodelay;
    limit_req zone=perserver burst=10;
}

 

이 지시문들은 현재 레벨에 `limit_req` 지시문이 정의되지 않은 경우에만 이전 구성 레벨에서 상속된다.

 

- 구문: `limit_req_dry_run on | off;`
- 기본값: `limit_req_dry_run off;`
- context: `http`, `server`, `location`

이 지시문은 버전 1.17.1에 등장했다. dry run 모드를 활성화한다. 이 모드에서는 요청 처리 속도가 제한되지 않지만, 공유 메모리 영역에서는 과도한 요청수가 평소와 같이 계산된다.

 

- 구문: `limit_req_log_level info | notice | warn | error;`
- 기본값: `limit_req_log_level error;`
- context: `http`, `server`, `location`

이 지시문은 0.8.18에 등장했다. 서버가 속도 초과로 인해 요청 처리를 거부하거나 요청 처리를 지연할 때 원하는 로그 레벨을 설정한다. 지연에 대한 로그 레벨은 거부에 대한 로그 레벨보다 한단계 낮다. 예를 들어 `limit_req_log_level notice`가 지정된 경우 지연은 `info` 레벨로 기록된다.

 

- 구문: `limit_req_status code;`
- 기본값: `limit_req_status 503;`
- 컨텍스트: `http`, `server`, `location`

이 지시문은 버전 1.3.15에 등장했다. 거부된 요청에 대한 응답으로 반환할 상태 코드를 설정한다.

 

- 구문: `limit_req_zone key zone=name:size rate=rate [sync];`
- 기본값: —
- 컨텍스트: `http`

다양한 키에 대한 상태를 유지할 공유 메모리 영역의 매개변수를 설정한다. 특히, 상태는 현재 과도한 요청 수를 저장한다. 키는 텍스트, 변수 및 그 조합을 포함할 수 있다. 빈 키값을 가진 요청은 계산되지 않는다.

 

버전 1.7.6 이전에는 키가 정확히 하나의 변수를 포함할 수 있었다.

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

 

여기서 상태는 10mb 영역 "one"에 저장되며, 이 영역의 평균 요청 처리 속도는 초당 1개의 요청을 초과할 수 없다.

 

클라이언트 IP 주소는 키로 사용된다. 여기서 `$remote_addr` 대신 `$binary_remote_addr` 변수를 사용한다. `$binary_remote_addr` 변수의 크기는 IPv4 주소의 경우 항상 4바이트, IPv6 주소의 경우 16바이트이다. 저장된 상태는 32비트 플랫폼에서는 항상 64바이트, 64비트 플랫폼에서는 128바이트를 차지한다. 1mb 영역은 약 16,000개의 64바이트 상태 또는 약 8,000개의 128바이트 상태를 유지할 수 있다.

 

영역 저장소가 소진되면 가장 최근에 사용되지 않은 상태가 제거된다. 그럼에도 불구하고 새 상태를 생성할 수 없는 경우 요청은 오류와 함께 종료된다.

 

속도는 초당 요청수(r/s)로 지정된다. 초당 1개 미만의 요청속도가 필요한 경우 분당 요청수(r/m)로 지정하면 된다. 예를 들어, 초당 반 요청은 30r/m이다.

 

`sync` 매개변수(1.15.3)는 공유 메모리 여역의 동기화를 활성화한다. `sync` 매개변수는 유료 기능의 일부로 제공된다. 유료 기능의 일부로 1.17.7 이후 API를 통해 각 공유 메모리 영역의 상태 정보를 얻거나 재설정할 수 있다.

내장 변수

- `$limit_req_status`: 요청 처리 속도 제한의 결과를 유지한다.

  `PASSED`, `DELAYED`, `REJECTED`, `DELAYED_DRY_RUN`, `REJECTED_DRY_RUN`