haproxy rate-limit 요청 제한

api의 과도한 요청은 시스템에 부담을 주고 시스템에 문제를 일으킬 수 있습니다.
이러한 과도한 요청을 막기 위해 api request에 대한 제한을 설정합니다.
haproxy의 rate-limit 기능을 이용하여 api request 요청을 제한하는 방법에 대해 알아보겠습니다.

rate-limit 이란

rate-limit은 웹 속성을 과도하게 사용하거나 남용하는 사용자, 봇 또는 애플리케이션을 차단합니다.
rate-limit은 특정 종류의 봇 공격을 막을 수 있습니다.
예를 들어 계정에 로그인을 시도하는 경우와 같이 특정 시간 내에 작업을 반복 할 수있는 빈도를 제한합니다.
rate-limit은 특정 종류의 악성 봇 활동을 중지하는 데 도움이 될 수 있고 웹 서버의 부담을 줄일 수 있습니다.

ip 기반 rate-limit 설정

ip를 기준으로 rate-limit 설정을 작성합니다.

rate-limit 설정은 frontend 및 backend에 적용이 가능합니다.


  • frontend에 설정
frontend http bind *:80 mode http option forwardfor timeout client 1m stick-table type ipv6 size 100k expire 30s store http_req_rate(10s) http-request track-sc0 src http-request deny deny_status 429 if { sc_http_req_rate(0) gt 10 } use_backend api
  • backend에 설정
backend api mode http timeout connect 10s timeout server 1m stick-table type ipv6 size 100k expire 30s store http_req_rate(10s) http-request track-sc0 src http-request deny deny_status 429 if { sc_http_req_rate(0) gt 10 } server api localhost:8090

stick-table: 클라이언트의 요청 카운터를 저장하는 key-value 저장소
type: 요청 카운터를 저장하는 key type (ip, ipv6, string, integer, binary)
size: stick-table 크기, expire가 없거나 지정된 갯수를 초과하면 오래된 키를 삭제
expire: stick-table key 유효 시간

위 예제에서는 frontend 또는 backend 한 군데에만 설정하면 적용이 됩니다.

rate-limit test

artillery를 이용하여 테스트를 진행하였습니다.

  • 테스트 시나리오를 작성합니다.
config: target: http://localhost:8080 phases: - duration: 1 arrivalRate: 20 scenarios: - name: 'rate limit test' flow: - get: url: "/"

1초 동안 20번의 request를 요청합니다.


  • 결과
All virtual users finished Summary report @ 17:16:46(+0900) 2021-06-02 Scenarios launched: 20 Scenarios completed: 20 Requests completed: 20 Mean response/sec: 13.89 Response time (msec): min: 3 max: 7 median: 4 p95: 6.5 p99: 7 Scenario counts: rate limit test: 20 (100%) Codes: 200: 10 429: 10

10번의 요청은 정상 처리 되었고 10번의 요청은 429 응답을 받았습니다.

이번 예제에서는 ip를 기준으로 rate-limit을 적용하였지만 url, url parameter, token, etc., ... 등등의 다양한 방법으로 rate-limit 적용이 가능합니다.

참고 사이트

+ Recent posts