서비스 안정성을 높이기 위해 Nginx는 백엔드 서버의 상태를 감지하고, 장애가 발생한 노드로 요청을 보내지 않도록 구성할 수 있습니다. 이를 위한 두 가지 접근 방식은 다음과 같습니다:
- 수동(패시브) 상태 확인: Nginx 기본 기능만으로 구현 가능하며, 소규모 또는 중간 규모 환경에 적합합니다.
- 능동(액티브) 상태 확인: 외부 모듈을 통해 주기적으로 백엔드 상태를 체크하며, 고가용성이 요구되는 프로덕션 시스템에 적합합니다.
수동 상태 감지를 통한 장애 감지 및 차단 (빠른 적용 권장)
Nginx 자체에는 능동적인 상태 확인 기능이 없지만, 실패 횟수와 타임아웃 설정을 활용해 장애 서버로의 요청 전달을 제어할 수 있습니다. 이 방식은 연결 실패나 타임아웃이 발생한 후 해당 서버를 일정 시간 동안 제외시키는 방식입니다.
핵심 설정 예제
# 백엔드 서버 그룹 정의
upstream backend_servers {
server 192.168.1.10:8080 max_fails=2 fail_timeout=20s;
server 192.168.1.11:8080 max_fails=2 fail_timeout=20s;
server 192.168.1.12:8080 backup; # 모든 주 서버가 다운되었을 때 사용
keepalive 16;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
# 타임아웃 설정
proxy_connect_timeout 3s;
proxy_send_timeout 8s;
proxy_read_timeout 8s;
# 장애 발생 시 다른 서버로 재시도
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 2;
proxy_next_upstream_timeout 10s;
# 기본 헤더 설정
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
주요 파라미터 설명
| 파라미터 | 설명 |
|---|---|
max_fails=2 | 지정된 시간 내에 2번 실패하면 서버를 비활성화로 간주함 |
fail_timeout=20s | 장애 판단 시간 창과 비활성화 유지 시간 모두 포함 |
proxy_next_upstream | 특정 오류 발생 시 다음 서버로 요청을 넘김 |
backup | 메인 서버들이 모두 실패했을 때만 사용됨 |
능동 상태 감지를 통한 정밀한 장애 대응 (프로덕션 환경 추천)
보다 신뢰성 있는 장애 감지를 위해서는 nginx_upstream_check_module 모듈을 컴파일하여 설치해야 합니다. 이 모듈은 백엔드 서버의 상태를 주기적으로 검사하고, 미리 정의된 조건에 따라 서버를 활성/비활성 상태로 관리합니다.
1. 모듈 컴파일 및 설치 절차
wget http://nginx.org/download/nginx-1.24.0.tar.gz
git clone https://github.com/yaoweibin/nginx_upstream_check_module.git
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
patch -p1 < ../nginx_upstream_check_module/check_1.20.1+.patch
./configure --prefix=/opt/nginx --add-module=../nginx_upstream_check_module
make && sudo make install
2. 능동 상태 확인 설정 추가
upstream backend_pool {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
check interval=3000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "GET /status HTTP/1.0\r\nHost: localhost\r\n\r\n";
check_http_expect_alive http_200 http_302;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend_pool;
proxy_connect_timeout 3s;
proxy_read_timeout 8s;
proxy_next_upstream error timeout http_502 http_504;
}
location /upstream_status {
check_status;
allow 127.0.0.1;
deny all;
}
}
설정 적용 후 확인 사항
- 백엔드 서버 하나를 강제 종료하거나 서비스를 중지합니다.
- 클라이언트에서 요청을 보냅니다. 정상 작동하는 서버로만 요청이 전달되어야 합니다.
- 로그(
/opt/nginx/logs/error.log)에서 연결 실패 메시지가 나타나지 않는지 확인합니다. /upstream_status경로에 접속하여 각 서버의 상태가 올바르게 표시되는지 확인합니다.
결론
- 수동 방식은 별도의 모듈 없이 기본 설정만으로도 충분히 효과적이며, 빠른 구현이 필요한 경우 유용합니다.
- 능동 방식은 외부 모듈을 필요로 하지만, 실시간 상태 확인이 가능해 더 정확한 장애 감지가 가능합니다.
- 두 방식 모두 타임아웃 관련 설정과 함께 사용해야 전체적인 안정성을 확보할 수 있습니다.