데릭 디용기 님의 "NGINX 쿡북" 책을 정리한 글입니다.
0. 소개
- 웹 트래픽 컨트롤러: 트래픽 경로를 결정하고 여러 속성값을 이용해 흐름을 제어할 수 있음
기능
- 특정 비율로 분기
- 요청 빈도, 연결 수, 대역폭 등을 제한
1. A/B 테스트
split_client 모듈
- 트래픽을 특정 비율로 나누는 모듈
split_clients "${remote_addr}AAA" $variant {
20.0% "backendv2";
* "backendv1";
}
location / {
proxy_pass http://$variant
}
구성 요소 | 설명 |
"${remote_addr}AAA" |
사용자 IP 주소 ($remote_addr)와 문자열 "AAA"를 결합하여 해시 생성
|
$variant | 요청을 분배할 변수 |
20.0% "backendv2"; | 전체 요청 중 20%를 "backendv2"로 보냄 |
* "backendv1"; | 나머지 80%를 "backendv1"로 보냄 |
2. GeoIP 모듈과 데이터베이스 활용하기
설치
1. GeoIP2 모듈 설치
git clone https://github.com/leev/ngx_http_geoip2_module.git
brew install geoip2
brew install libmaxminddb
2. GeoIP2 모듈 빌드하기
nginx -V 2>&1 | egrep "^configure" | cut -d: -f2 > /tmp/nginx_build_options.txt
echo " --with-http_geoip_module" >> /tmp/nginx_build_options.txt
# ngx_http_geoip2_module 빌드하기
sh -c "./configure $(cat /tmp/nginx_build_options.txt) --add-dynamic-module=/path/to/ngx_http_geoip2_module"
make modules
- 빌드 플래그를 기존의 nginx와 일치시켜줘야 함
- geoip를 동적 모듈로 추가해주기
2. GeoIP2 사이트에서 country & city 정보 다운로드 (csv format)
3. 동적 모듈 적용하기 (설정 파일)
load_module modules/ngx_http_geoip_module.so
http {
geoip2 /usr/local/etc/nginx/geoip/GeoLite2-Country.mmdb { # 국가 데이터베이스를 불러옴
auto_reload 5m; # 5분마다 새로 로드
$geoip2_metadata_country_build metadata build_epoch; # 빌드 날짜를 저장하는 변수
$geoip2_data_country_code default=KR # 변수에 IP 주소 기반 국가 코드를 저장함
source=$variable_with_ip country iso_code;
$geoip2_data_country_name country name en; # 변수에 IP 주소 기반 국가 이름을 저장함
}
geoip2 /usr/local/etc/nginx/geoip/GeoLite2-City.mmdb { # 도시 데이터베이스를 불러옴
$geoip2_data_city_name default=Seoul city names en; # 변수에 IP 주소 기반 도시 이름을 저장함
}
# GeoIP2에서 가져온 정보를 FastCGI 서버에 전달
fastcgi_param COUNTRY_CODE $geoip2_data_country_code;
fastcgi_param COUNTRY_NAME $geoip2_data_country_name;
fastcgi_param CITY_NAME $geoip2_data_city_name;
}
- 다운로드받은 데이터베이스를 직접 이용할 수 있음
내장 변수
GeoIP2 모듈에서 사용 가능한 내장 변수를 쓸 수 있게 해줌
변수 | 설명 | 예제 값 |
$geoip2_metadata_country_build | GeoIP2 데이터베이스의 빌드 날짜 (epoch) | 1696891200 |
$geoip2_data_country_code | 방문자의 국가 코드 (ISO 3166-1 alpha-2) | DE, CN, BR |
$geoip2_data_country_name | 방문자의 국가 이름 | Germany, China, Brazil |
$geoip2_data_city_name | 방문자의 도시 이름 | Berlin, Tokyo |
$geoip2_data_region_name | 방문자의 지역/주 이름 | California, Seoul |
$geoip2_data_region_code | 방문자의 지역 코드 (ISO 3166-2) | CA, 11 |
$geoip2_data_latitude | 방문자의 위도 (도시 기반) | 48.8566 |
$geoip2_data_longitude | 방문자의 경도 (도시 기반) | 2.3522 |
$geoip2_data_timezone | 방문자의 타임존 | America/New_York |
$geoip2_data_asn | 방문자의 ASN (Autonomous System Number) | AS15169 |
$geoip2_data_isp | 방문자의 ISP (Internet Service Provider) | Google LLC |
$geoip2_data_organization | 방문자의 소속 조직 | Google Cloud |
$geoip2_data_connection_type | 방문자의 네트워크 유형 | Cable/DSL |
$geoip2_data_is_proxy | 방문자가 프록시를 사용하는지 여부 | yes / no |
3. 국가 단위 접근 차단하기
http {
map $geoip_country_code $country_access {
"US" 0;
default 1;
}
server {
if ($country_access = '1') { return 403; }
}
}
4. 프록시 서버로부터 온 트래픽의 사용자 IP 찾기
http {
# ============ 설정 =============
geoip2_proxy 10.0.16.0/26; # 프록시 서버의 IP 대역 지정 (CIDR 표기법)
geoip2_proxy_recursive on; # 최종 사용자의 IP 확인 (X-Forwarded-For 헤더값을 순차적으로 탐색)
}
geoip2_proxy
- 프록시 서버를 통해 요청이 전달되면 nginx가 직접 클라이언트 IP를 확인할 수 없음
- 프록시 서버는 대신 X-Forwarded-For 헤더에 클라이언트 IP를 담아서 전달함
- X-Forwarded-For 헤더값을 추출하기 위해 사용
5. 연결 제한하기
http {
# ============ 설정 =============
limit_conn_zone $binary_remote_addr zone=limitbyaddr:10m;
limit_conn_status 429;
server {
# ...
limit_conn limitbyaddr 40;
}
}
지시어 | 설명 |
limit_conn_zone | 공유 메모리 영역을 생성 키(사용자 IP 등)를 바이너리 형태로 변환하여 저장 |
$binary_remote_addr | 사용자 IP를 바이너리 형태로 변환한 값 (키 역할) |
limit_conn_status | 제한 초과 시 응답할 HTTP 상태 코드 지정 |
limit_conn |
특정 공유 메모리 영역에 대해 최대 동시 연결 수 제한
|
6. 요청 빈도 제한하기
http {
# ============ 설정 =============
limit_req_zone $binary_remote_addr zone=limitbyaddr:10m rate=3r/s;
limit_conn_status 429;
server {
# ...
limit_req limitbyaddr 40;
}
}
지시어 | 설명 |
limit_req_zone | 요청 속도 제한을 위한 공유 메모리 영역을 생성 |
$binary_remote_addr | 사용자 IP를 바이너리 형태로 변환 (키 역할) |
zone=limitbyaddr:10m | 공유 메모리 이름(limitbyaddr)과 크기(10MB, 약 160,000개 IP 저장 가능) 지정 |
rate=3r/s | 1초당 3개의 요청만 허용 (r/s: requests per second) |
limit_conn_status | 제한 초과 시 반환할 HTTP 상태 코드 |
limit_req | 특정 공유 메모리(limitbyaddr)에서 허용할 최대 요청 대기열 크기 지정 |
7. 전송 대역폭 제한하기
server {
location /download/ {
limit_rate_after 10m;
limit_rate 1m;
}
}
지시어 | 설명 |
limit_rate_after | 지정된 크기(바이트 단위) 이후부터 대역폭 제한 적용 |
limit_rate | 클라이언트당 초당 다운로드 속도를 제한 (바이트 단위) |
출처
'Network' 카테고리의 다른 글
[NGINX 쿡북] 2. 고성능 부하분산 (0) | 2025.04.01 |
---|---|
[NGINX 쿡북] 1. 엔진엑스 기초 (0) | 2025.04.01 |
[러닝 HTTP/2] 5. HTTP/2 프로토콜 (0) | 2025.03.30 |
[러닝 HTTP/2] 4. HTTP/2로의 전환 (0) | 2025.03.30 |
[러닝 HTTP/2] 3. 웹을 파헤치는 이유와 방법 (0) | 2025.03.30 |