Nginx에서 URI 별로 간단하게 로드밸런싱을 적용 할 수 있다는 사실을 알게 되었다.
물론 Spring에서도 Bucket4j 를 활용해 제한할 수 있지만, 우선 현재 정책상 유저의 권한에 따른 차등 정책이 없기 때문에 웹 서버단에서 전체적으로 Request를 조절해 보려고 한다. (ex: brute force 공격을 막기 위해 로그인 URI를 보호한다던지..)
적용법은 의외로 간단하다. (해당 설명은 nginx 1.14.0을 기준으로 진행됩니다. 버전별 설정 적용 부분이 상이 할 수 있습니다.)
cd /etc/nginx
# edit config
vi nginx.conf
# http body에 다음 추가후 저장
limit_req_zone $binary_remote_addr zone=bingolimit:10m rate=10r/s;
limit_req_status 429;
limit_req_status는 limit 한도를 넘었을때 던질 http status를 의미한다. 서버 오류를 던지는 경우에 503을 던지긴 하지만, 클라이언트 에러코드로 처리하는게 더 알맞다고 생각하여 본인은 429로 설정했다.
여기서 가장 중요한 부분은 limit_req_zone을 bingolimit이라는 이름으로 하나 만들거라는 부분이 중요하다.
10m은 임시로 생성되는 공유메모리의 크기를 10mb로 설정하겠다 이고, rate=10r/s는 1초에 10번의 요청을 처리한다. 즉 30번의 요청 처리에는 3초가 걸리게 된다로 이해하면 된다.
nginx.conf 설정이 끝나면 본인의 도메인 설정에서 어떤 URI 해당 설정을 적용할지 결정해야 한다.
cd sites-available
vi ${your_domain}
# server의 특정 URI에 limit_req_zone을 적용후 저장
location / { # location 블록
limit_req zone=bingolimit burst=20 nodelay;
}
본인은 우선 루트 경로에 해당 설정을 적용해줬다. 여기서 burst가 의미하는 바는 bucket4j의 token bucket 알고리즘 처럼 큐의 최대 사이즈를 의미한다. 최대 20개의 요청까지는 대기열에 저장이 가능하다는 의미다. 즉 동시에 23개 요청이 들어오면 1(처리), 20(대기), 2(FAIL) 처리가 되는것이다. 뒤에 nodelay를 붙여준 이유는 딜레이를 없애 지연 응답을 없애기 위해서 적용해줬다. 해당 옵션은 본인의 서비스 특성을 고려하여 적용해주면 된다.
'Infra' 카테고리의 다른 글
MySQL access denied for user 'root'@'localhost' (using password: yes) (0) | 2024.03.03 |
---|---|
Kafka 설치 및 세팅 (0) | 2024.02.25 |
Nginx - 로그 포맷 설정 (0) | 2024.01.24 |
Git - postBuffer size 조절 (0) | 2024.01.21 |
Nginx 해외 IP 차단 (0) | 2024.01.21 |