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 적용이 가능합니다.