본문으로 건너뛰기

Apache mod_proxy_balancer 로드밸런싱

Apache HTTPD는 mod_proxy_balancer 모듈을 통해 강력한 로드밸런싱 기능을 제공합니다. balancer:// 스킴으로 업스트림 그룹을 정의하고, 다양한 분산 알고리즘(lbmethod)으로 요청을 분배할 수 있습니다.


필요 모듈 활성화​

Apache에서 로드밸런싱을 사용하려면 다음 모듈이 활성화되어야 합니다.

# Ubuntu/Debian
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests # Round Robin
sudo a2enmod lbmethod_bytraffic # 트래픽 기반
sudo a2enmod lbmethod_bybusyness # 최소 연결
sudo a2enmod slotmem_shm # 공유 메모리 (balancer 필수)
sudo systemctl restart apache2

# CentOS/RHEL (httpd.conf에서 주석 해제)
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so

모듈 활성화 확인:

apache2ctl -M | grep -E "proxy|balancer|lbmethod"

기본 로드밸런서 구성​

가장 단순한 설정 (byrequests)​

# /etc/apache2/sites-available/load-balancer.conf

<VirtualHost *:80>
ServerName example.com

ProxyRequests Off
ProxyPreserveHost On

# 업스트림 그룹 정의
<Proxy "balancer://mycluster">
BalancerMember "http://10.0.0.1:8080"
BalancerMember "http://10.0.0.2:8080"
BalancerMember "http://10.0.0.3:8080"

ProxySet lbmethod=byrequests # Round Robin
</Proxy>

# 모든 요청을 로드밸런서로 전달
ProxyPass "/" "balancer://mycluster/"
ProxyPassReverse "/" "balancer://mycluster/"
</VirtualHost>

lbmethod 알고리즘 상세​

byrequests (요청 수 기반, Round Robin)​

각 서버가 처리한 요청 수를 기준으로 가중치에 따라 분배합니다. 기본적으로 Round Robin과 동일하게 동작합니다.

<Proxy "balancer://mycluster">
BalancerMember "http://10.0.0.1:8080" loadfactor=3
BalancerMember "http://10.0.0.2:8080" loadfactor=1
ProxySet lbmethod=byrequests
</Proxy>

loadfactor는 Nginx의 weight와 동일한 역할입니다. 위 설정에서 App1은 전체의 75%, App2는 25%를 처리합니다.

bytraffic (트래픽 바이트 기반)​

처리한 트래픽(바이트)을 기준으로 분배합니다. 파일 다운로드처럼 응답 크기가 크게 다를 때 유용합니다.

<Proxy "balancer://mycluster">
BalancerMember "http://10.0.0.1:8080"
BalancerMember "http://10.0.0.2:8080"
ProxySet lbmethod=bytraffic
</Proxy>

100MB 파일을 받는 요청과 1KB API 응답을 받는 요청이 혼재할 때, byrequests는 단순히 요청 수를 세지만 bytraffic은 실제 처리한 데이터량을 기준으로 합니다. 이미지·동영상 서빙 서버에 적합합니다.

bybusyness (최소 활성 요청)​

현재 처리 중인 요청 수가 가장 적은 서버로 보냅니다. Nginx의 least_conn과 유사합니다.

<Proxy "balancer://mycluster">
BalancerMember "http://10.0.0.1:8080"
BalancerMember "http://10.0.0.2:8080"
BalancerMember "http://10.0.0.3:8080"
ProxySet lbmethod=bybusyness
</Proxy>

응답 시간이 긴 API 서버나 DB 쿼리가 많은 백엔드에 적합합니다.

heartbeat (헬스비트 기반, 실험적)​

백엔드 서버에서 보내는 헬스비트 정보를 바탕으로 부하를 판단합니다. mod_heartbeat, mod_heartmonitor 모듈과 함께 사용합니다. 특수한 환경에서만 사용하므로 일반적으로는 위 세 가지 중 선택합니다.


BalancerMember 파라미터 완전 정리​

<Proxy "balancer://mycluster">
BalancerMember "http://10.0.0.1:8080"
loadfactor=3 # 가중치 (기본값: 1, 높을수록 요청 많이 받음)
retry=60 # 장애 후 재시도 간격(초), 0이면 무한 배제
timeout=30 # 연결 타임아웃(초)
acquire=3000 # 연결 대기 최대 시간(ms)
max=100 # 최대 동시 연결 수
ttl=60 # 유휴 연결 유지 시간(초)
route=jvm1 # mod_jk와 연동 시 JVM 라우트 ID
status=+H # 상태 강제 설정 (H=Hot Standby, D=Disabled, S=Stop, I=Ignore errors)

BalancerMember "http://10.0.0.2:8080" loadfactor=1 status=+H
# +H: Hot Standby — 다른 모든 서버 다운 시에만 사용

ProxySet lbmethod=bybusyness
ProxySet stickysession=JSESSIONID # 세션 고정
</Proxy>

status 플래그 설명​

플래그의미사용 시기
+DDisabled수동 점검 시 트래픽 차단
+HHot Standby예비 서버 (평시에는 사용 안 함)
+SStopped새 연결 차단, 기존 연결 유지
+IIgnore errors오류 무시 (헬스체크 제외)
-D플래그 제거다시 활성화

Sticky Session (세션 고정)​

세션 기반 애플리케이션에서 같은 사용자가 항상 같은 서버로 연결되도록 설정합니다.

쿠키 기반 Sticky Session (권장)​

<Proxy "balancer://mycluster">
BalancerMember "http://10.0.0.1:8080" route=server1
BalancerMember "http://10.0.0.2:8080" route=server2
BalancerMember "http://10.0.0.3:8080" route=server3

ProxySet lbmethod=byrequests
ProxySet stickysession=JSESSIONID # Tomcat 기본 세션 쿠키명
</Proxy>

Tomcat의 server.xml에서 jvmRoute를 설정해야 합니다:

<!-- server.xml -->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="server1">

이렇게 하면 Tomcat이 세션 ID에 .server1을 붙여 반환합니다:

Set-Cookie: JSESSIONID=ABC123.server1; Path=/

Apache는 이 쿠키를 읽어 route=server1인 서버로 라우팅합니다.

URL 기반 Sticky Session​

쿠키를 사용할 수 없는 환경에서 URL에 라우팅 정보를 포함합니다:

ProxySet stickysession=jsessionid|JSESSIONID  # URL 파라미터명|쿠키명

URL 예시: http://example.com/app;jsessionid=ABC123.server1


Balancer Manager (웹 관리 인터페이스)​

Apache는 브라우저에서 로드밸런서 상태를 모니터링하고 실시간으로 설정을 변경할 수 있는 관리 페이지를 제공합니다.

# /etc/apache2/conf-available/balancer-manager.conf

<Location "/balancer-manager">
SetHandler balancer-manager
Require ip 127.0.0.1 10.0.0.0/8 # 내부 네트워크만 접근 허용
</Location>
# Ubuntu
sudo a2enconf balancer-manager
sudo systemctl reload apache2

# 접속
curl http://localhost/balancer-manager

관리 페이지에서 할 수 있는 작업:

  • 각 서버의 상태, 요청 수, 오류 수 확인
  • 서버 비활성화/활성화 (점검 중 사용)
  • 가중치(loadfactor) 실시간 변경
  • 세션 데이터 초기화

실전 구성: 완전한 로드밸런서 설정​

# /etc/apache2/sites-available/production-lb.conf

<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com

ProxyRequests Off
ProxyPreserveHost On

# 헤더 설정
Header add X-Forwarded-Proto "http"
RequestHeader set X-Forwarded-Proto "http"

# 메인 앱 클러스터
<Proxy "balancer://appcluster">
BalancerMember "http://10.0.0.1:8080" loadfactor=3 retry=5 route=jvm1
BalancerMember "http://10.0.0.2:8080" loadfactor=3 retry=5 route=jvm2
BalancerMember "http://10.0.0.3:8080" loadfactor=1 retry=5 route=jvm3 status=+H

ProxySet lbmethod=bybusyness
ProxySet stickysession=JSESSIONID
ProxySet nofailover=Off
</Proxy>

# 정적 파일 클러스터
<Proxy "balancer://staticcluster">
BalancerMember "http://10.0.1.1:80" loadfactor=1
BalancerMember "http://10.0.1.2:80" loadfactor=1
ProxySet lbmethod=byrequests
</Proxy>

# 정적 파일: 별도 클러스터
ProxyPass "/static/" "balancer://staticcluster/static/"
ProxyPassReverse "/static/" "balancer://staticcluster/static/"

# 관리자 페이지: 단일 서버 (로드밸런싱 제외)
ProxyPass "/admin/" "http://10.0.0.1:8080/admin/"
ProxyPassReverse "/admin/" "http://10.0.0.1:8080/admin/"

# 나머지 모든 요청: 앱 클러스터
ProxyPass "/" "balancer://appcluster/"
ProxyPassReverse "/" "balancer://appcluster/"

# 타임아웃 설정
ProxyTimeout 60

# 에러 페이지
ErrorDocument 503 /error/503.html
ProxyPass "/error/" "!" # /error/는 로컬 처리

# Balancer Manager (내부 접근만 허용)
<Location "/balancer-manager">
SetHandler balancer-manager
Require ip 127.0.0.1 10.0.0.0/8
</Location>

# 로그
CustomLog /var/log/apache2/lb-access.log combined
ErrorLog /var/log/apache2/lb-error.log
</VirtualHost>

설정 검증 및 테스트​

# 설정 문법 확인
sudo apache2ctl configtest

# 적용
sudo systemctl reload apache2

# 로드밸런싱 동작 확인
for i in {1..9}; do
curl -s -o /dev/null -w "%{http_code} - upstream\n" http://example.com/
done

# 로그에서 백엔드 서버 확인 (mod_proxy는 X-Forwarded-For 헤더에 기록)
tail -f /var/log/apache2/lb-access.log

# 현재 balancer 상태 확인
curl -s http://localhost/balancer-manager | grep -E "worker|status|loadfactor"

알고리즘 선택 가이드​

상황권장 lbmethod
단순 균등 분배, 동일 스펙 서버byrequests
파일 다운로드, 미디어 스트리밍bytraffic
API 서버, 처리 시간 불균일bybusyness
세션 공유 없는 기존 앱byrequests + stickysession

다음 페이지에서는 mod_jk를 이용한 AJP 기반 로드밸런싱을 알아봅니다.