개요
이번 게시글에서는 HAProxy 를 사용하여 로드 밸런싱을 구현하는 방법을 기록해보려고 한다.
웹 서비스의 트래픽이 증가함에 따라 효율적인 로드 밸런싱은 안정적인 서비스 제공을 위해 필수적이다.
이제 HAProxy의 개념부터 실제 구현 방법까지 단계적으로 실습해보자.
1. HAProxy란?
HAProxy는 High Availability Proxy의 약자로, TCP와 HTTP 기반의 로드 밸런서이자 프록시 서버이다.
대규모 트래픽을 효율적으로 분산시켜 서버의 부하를 줄이고 고가용성을 보장한다.
- 고성능: 수만 개의 동시 연결 처리 가능
- 유연성: 다양한 프로토콜과 로드 밸런싱 알고리즘 지원
- 안정성: 서버 장애 시 자동으로 트래픽을 다른 서버로 전환
2. 준비물
- 리눅스 서버: HAProxy를 설치할 서버 (Ubuntu, CentOS)
- 웹 서버들: 실제로 웹 요청을 처리할 백엔드 서버 (Nginx)
- 관리자 권한: 패키지 설치 및 시스템 설정을 위해 필요
3. HAProxy 설치하기
Debian 계열
sudo apt-get update -y
sudo apt-get install -y haproxy -y
RHEL 계열
sudo yum install haproxy -y
설치 후 HAProxy 버전을 확인하여 정상 설치 되었는지 확인하자.
haproxy -v
4. HAProxy 구성 파일 설정
구성 파일은 /etc/haproxy/haproxy.cfg
에 위치한다. (수정하기 전에 백업을 권장)
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
sudo vim /etc/haproxy/haproxy.cfg
기본 구성 예시
global
log /dev/log local0
maxconn 2000
daemon
defaults
log global
mode http
option httplog
timeout connect 5000
timeout client 50000
timeout server 50000
frontend http_front
bind *:80
default_backend http_back
backend http_back
balance roundrobin
server web1 192.168.1.101:8080 check
server web2 192.168.1.102:8080 check
server web3 192.168.1.103:8080 check
구성 요소 설명
- global 섹션: HAProxy의 전역 설정을 정의
- defaults 섹션: 기본 동작 방식을 설정
- frontend 섹션: 클라이언트로부터의 요청을 수신
- backend 섹션: 요청을 처리할 실제 서버들을 정의
- 여기서
web1
,web2
,web3
은 백엔드 서버의 이름을 의미함. - HAProxy 구성 파일에서 각 백엔드 서버를 식별할 수 있도록 임의의 이름을 지정. (이 이름은 HAProxy 내부에서만 사용됨.)
- 실제 서버의 호스트 이름이나 IP 주소와는 무관.
- 여기서
4-1. 로드 밸런싱 알고리즘 이해하기
로드 밸런싱 알고리즘은 트래픽을 어떻게 분산할지 결정한다.
- roundrobin: 서버에 순차적으로 요청을 분배
- leastconn: 가장 적은 연결을 가진 서버에 요청 전송
- source: 클라이언트의 IP 주소를 기반으로 요청 분배
환경에 맞는 알고리즘을 선택해 효율적인 로드 밸런싱을 구현해야 한다.
4-2. 헬스 체크 설정
헬스 체크 (check) 옵션
각 서버 뒤에 check
를 추가하면 HAProxy가 해당 서버의 상태를 주기적으로 확인한다.
서버가 응답하지 않으면 자동으로 트래픽 분배에서 제외된다.
server web1 192.168.1.101:8080 check
4-3. 모니터링 설정
HAProxy의 실시간 상태를 모니터링하기 위해 통계 페이지를 활성화할 수 있다.
설정 추가
/etc/haproxy/haproxy.cfg
파일에 아래 설정을 추가하자.
listen stats
bind *:8050
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:password
브라우저에서 http://서버_IP:8050/stats
로 접속하여 확인 가능하다.
5. SSL/TLS 설정으로 HTTPS 지원하기
HTTPS를 지원하려면 SSL 인증서가 필요하다.
인증서 준비
인증서와 개인 키를 .pem
파일로 결합하자.
cat your_cert.crt your_key.key > /etc/ssl/certs/haproxy.pem
구성 파일 수정
/etc/haproxy/haproxy.cfg
구성파일을 수정해주자.
frontend https_front
bind *:443 ssl crt /etc/ssl/certs/haproxy.pem
default_backend http_back
6. 세션 지속성 및 고급 설정
세션 지속성 (Sticky Sessions)
로그인 세션 등을 유지하기 위해 동일한 클라이언트의 요청을 같은 서버로 보내야할 때 사용됨.
backend http_back
balance roundrobin
cookie SERVERID insert indirect nocache
server web1 192.168.1.101:8080 check cookie web1
server web2 192.168.1.102:8080 check cookie web2
ACL (Access Control List) 활용
특정 조건에 따라 트래픽 분배 가능
frontend http_front
bind *:80
acl is_api path_beg /api
use_backend api_back if is_api
default_backend http_back
7. 문제 해결 방법
구성 파일 검사
구성 파일에 오류가 없는지 확인
haproxy -c -f /etc/haproxy/haproxy.cfg
로그 확인
로그 파일을 통해 오류 원인 파악
sudo tail -f /var/log/haproxy.log
서비스 상태 확인
HAProxy의 서비스 상태 확인
sudo systemctl status haproxy
8. 로드 밸런싱 테스트 결과
로드 밸런싱 설정을 완료한 후, 실제로 트래픽이 백엔드 서버로 정상 분산되는지 확인하기 위해 아래와 같은 테스트를 진행해보자.
8-1. 테스트 환경
- 클라이언트: HAProxy 로드 밸런서에 HTTP 요청 전송
- HAProxy 서버: 앞서 설정한 로드 밸런서를 구동 중임.
- 백엔드 서버들: 세 대의 웹 서버(
web1
,web2
,web3
)가 각각 자신을 식별할 수 있는 간단한 웹 페이지 호스팅 중
8-2. 테스트 방법
1. Curl을 이용한 요청 전송
클라이언트 머신에서 반복적으로 HTTP 요청을 보내 응답 확인
for i in {1..10}; do sleep 1; curl http://your-haproxy-server-ip; done
2. 웹 브라우저를 통한 확인
웹 브라우저에서 http://your-haproxy-server-ip
로 여러 번 접속하여 각 요청에 대한 응답을 확인
8-3. 기대 결과
- Round Robin 알고리즘에 따라 요청이 순차적으로 각 백엔드 서버로 분산된다.
- 각 요청의 응답 내용에 해당 서버의 식별자(
hostname
)가 표시된다.
8-4. 실제 결과
Curl 명령 실행 결과
요청을 보낼 때마다 백엔드 서버의 의 응답이 순서대로 돌아왔음
웹 브라우저 확인 결과
페이지를 새로고침할 때마다 다른 웹 서버의 hostname
이 출력됨.
8-5. 부하 테스트 (선택 사항)
추가로 부하 테스트 도구인 **ApacheBench (ab)**를 사용하여 동시 접속 시의 로드 밸런싱 테스트도 가능하다.
ab -n 100 -c 10 http://your-haproxy-server-ip/
-n 100
: 총 100개의 요청을 보냄.-c 10
: 동시에 10개의 요청을 보냄
8-6. 결과
- 응답 시간과 처리량이 안정적으로 유지되었으며, 백엔드 서버들로 요청이 균등하게 분배됨.
- 각 서버의 자원 사용률을 모니터링한 결과, 부하가 고르게 분산되었음을 확인함.