NGINX: 대기열에 있는 쿼리에 대한 요청 제한 시간 초과 동작(버스트)

NGINX: 대기열에 있는 쿼리에 대한 요청 제한 시간 초과 동작(버스트)

현재 대기열 크기는 3000개 요청입니다.

location /api/v2 {
     limit_req zone=bursted burst=3000;
     include /etc/nginx/proxy.conf;
 }

비율 제한은 초당 요청 10개입니다.

 limit_req_zone $limit zone=api_slow:10m rate=1r/s;
 limit_req_zone $server_name zone=bursted:10m rate=10r/s;

연결 유지 시간 제한은 30초입니다. 즉, 대기열이 가득 차면 30초마다 오류 코드 408과 함께 2700개의 요청이 거부되어야 합니다.

 reset_timedout_connection on;
 client_body_timeout 10;
 send_timeout 2;
 keepalive_timeout 30;

출퇴근 시간에는 요청이 서블릿 컨테이너로 전달되기 위해 대기열에서 대기하는 동안 시간 초과로 인해 NGINX에서 오류 코드 408로 거부된 요청을 로그에서 찾을 수 없었습니다. 요청 속도 오버헤드에 해당하는 503 오류 코드로만 거부합니다.

delaying request, excess: 2958.320, by zone "bursted"
limiting requests, excess: 3000.730 by zone "bursted"

NGINX는 이러한 대기열의 요청이 너무 오래 정지되면 시간 초과로 요청을 거부합니까? 이 시간 초과는 무엇입니까? 구성은 어디에 있습니까?

답변1

nginx 속도 제한 및 시간 초과가 작동하는 방식에 약간의 혼란이 있는 것 같습니다. 없다시간 초과속도 제한용. 속도와 대기열 크기만 설정하면 됩니다. 속도를 초과하는 요청은 나중에 처리하기 위해 대기열에 추가됩니다. 대기열이 완전히 채워지면 추가 요청은 503 상태 코드와 함께 거부됩니다.


귀하의 예에서초당 요청 10개(10r/s)의 속도를 설정했으며 버스트 크기는 3000이고 영역은 10MB 크기로 '버스트'되었습니다. 그리고 이 비율 제한은 정의된 각 서버에 대해 별도의 개수로 적용됩니다.

즉, 서버는 0.1초마다 하나의 요청을 수락하고 처리하며 최대 3000개의 초과 요청을 대기열에 추가할 수 있으며, 해당 요청은 정의된 속도(0.1초마다 하나씩)로 처리됩니다. 그리고 버스트 영역은 약 160,000개의 IP 주소를 저장할 수 있습니다.

그 의미는3011개의 요청이 1초 이내에 도착하면 nginx는 처음 10개의 요청을 즉시 처리하고 다른 3000개의 요청을 대기열에 넣으며 3011번째 요청은 503 상태 코드와 함께 거부됩니다. 그러면 대기열은 0.1초마다 1개의 요청이라는 정의된 속도로 처리됩니다. 새 요청이 도착하지 않는 한 대기열은 점점 짧아지고 새 요청이 대기열에 다시 추가될 수 있습니다. 그러나 대기열에 이미 3000개의 요청이 보관되어 있는 동안 모든 추가 요청은 503 상태 코드와 함께 거부됩니다.

이러한 버스트 대기열의 선형 처리 동작으로 인해 사이트가 느리게 보일 수 있습니다. 이를 방지하려면 매개 nodelay변수를 limit_req zone=bursted burst=3000 nodelay;. 이렇게 하면 버스트 대기열의 모든 요청이 즉시 처리되면서 대기열의 슬롯을 '사용'으로 표시한 다음 다시 정의된 속도로 슬롯별로 '해제'되므로 시간이 지남에 따라 정의된 속도 제한이 충족됩니다.

limit_req_status 444;참고: 구성 블록 에 추가하여 거부된 요청의 상태 코드를 503에서 444로 변경할 수 있습니다 http.

자세한 내용은 다음을 참조하세요.


구성의 두 가지 시간 초과:

이렇게 client_body_timeout 10;하면 요청 후 클라이언트 본문이 전송될 때까지 서버가 최대 10초 동안 기다리게 됩니다. 이 시간 내에 클라이언트에서 본문이 전송되지 않으면 서버는 408 상태 코드로 연결을 종료합니다.

이렇게 하면 keepalive_timeout 30;30초 후에도 열려 있는 클라이언트에 대한 모든 연결이 서버에서 닫힙니다. 그러나 내 테스트에 따르면 버스트 대기열에서 요청이 대기하는 시간은 keepalive_timeout에 포함되지 않습니다.


부하 테스트 수행사용하여ab또는포위.

관련 정보