Apache httpd-Tomcat mod_proxy 연동
Apache HTTP Server의 mod_proxy로 Tomcat에 HTTP Reverse Proxy를 구성하는 방식과 점검 포인트를 정리한다.
mod_proxy 요청 경로
Client
-> Apache HTTP Server
-> mod_proxy / mod_proxy_http
-> Tomcat HTTP Connector
mod_proxy 방식은 Apache HTTP Server가 HTTP 요청을 받아 Tomcat의 HTTP Connector로 다시 전달하는
구성이다.
연동 방식 요약
mod_proxy는 Apache HTTP Server를 Reverse Proxy로 동작하게 하고, mod_proxy_http는 HTTP 방식의
backend 연결을 담당한다.
언제 쓰는가
| 상황 | 판단 |
|---|---|
Tomcat이 8080 HTTP Connector로 열려 있음 | mod_proxy_http가 단순하고 직관적 |
| HTTPS는 Apache HTTP Server에서 종료 | Tomcat에는 원래 scheme 정보를 헤더로 전달 |
| 여러 Tomcat으로 분산 | mod_proxy_balancer와 BalancerMember 검토 |
| 오래된 AJP 기반 구성이 이미 있음 | mod_jk나 mod_proxy_ajp 문서도 함께 확인 |
새로 구성한다면 HTTP reverse proxy가 보통 이해하기 쉽다. 운영자가 curl로 Tomcat backend를 직접
확인할 수 있고, 설정도 ProxyPass 중심으로 읽힌다.
필요한 모듈
| 모듈 | 역할 |
|---|---|
mod_proxy | 프록시 공통 기능 |
mod_proxy_http | HTTP backend 연결 |
mod_headers | X-Forwarded-Proto 같은 헤더 설정 |
mod_ssl | HTTPS 종료가 Apache HTTP Server에서 일어날 때 필요 |
mod_proxy_balancer | 여러 backend로 분산할 때 필요 |
apachectl -M | grep proxy
proxy_module, proxy_http_module이 보이지 않으면 설정 파일보다 모듈 로딩부터 확인한다.
기본 설정
<VirtualHost *:80>
ServerName example.com
ProxyRequests Off
ProxyPreserveHost On
ProxyPass "/" "http://127.0.0.1:8080/" connectiontimeout=5 timeout=60
ProxyPassReverse "/" "http://127.0.0.1:8080/"
ErrorLog logs/example-error.log
CustomLog logs/example-access.log combined
</VirtualHost>
ProxyRequests Off는 forward proxy를 켜지 않겠다는 의미다. Reverse Proxy 구성에서는 보통 Off로
둔다. ProxyPass는 요청을 보낼 backend를 정하고, ProxyPassReverse는 backend가 만든 redirect
헤더를 앞단 URL 기준으로 보정한다.
HTTPS 앞단 설정
<VirtualHost *:443>
ServerName example.com
SSLEngine On
SSLCertificateFile /etc/pki/tls/certs/example.crt
SSLCertificateKeyFile /etc/pki/tls/private/example.key
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ProxyPass "/" "http://127.0.0.1:8080/" connectiontimeout=5 timeout=60
ProxyPassReverse "/" "http://127.0.0.1:8080/"
</VirtualHost>
TLS가 Apache HTTP Server에서 끝나면 Tomcat 입장에서는 HTTP 요청처럼 보인다. 애플리케이션이 HTTPS
redirect, secure cookie, callback URL을 다룬다면 X-Forwarded-Proto 같은 헤더와 애플리케이션의
proxy 설정을 함께 맞춰야 한다.
로드밸런싱 예시
<Proxy "balancer://tomcat_cluster">
BalancerMember "http://127.0.0.1:8080" route=tomcat1
BalancerMember "http://127.0.0.1:8081" route=tomcat2
ProxySet stickysession=JSESSIONID
</Proxy>
<VirtualHost *:80>
ServerName example.com
ProxyPass "/" "balancer://tomcat_cluster/"
ProxyPassReverse "/" "balancer://tomcat_cluster/"
</VirtualHost>
세션을 Tomcat 메모리에만 저장한다면 sticky session이 필요할 수 있다. 세션을 외부 저장소나 클러스터 복제로 관리한다면 sticky session 의존도를 낮출 수 있다.
장애별 확인
| 증상 | 확인 지점 |
|---|---|
| 502 | Tomcat 포트, firewall, ProxyPass URL, backend 기동 상태 |
| 503 | balancer member down, health check, worker 오류 |
| redirect loop | HTTPS 종료 위치, X-Forwarded-Proto, 애플리케이션 proxy 설정 |
| Host 불일치 | ProxyPreserveHost, 애플리케이션 base URL |
| 느린 응답 | timeout, Tomcat thread, DB 응답 시간 |
점검 명령
apachectl configtest
apachectl -M | grep proxy
curl -I http://127.0.0.1:8080/
curl -I http://example.com/
tail -f /var/log/httpd/error_log
tail -f $CATALINA_BASE/logs/catalina.out
먼저 Tomcat backend에 직접 붙어 응답을 확인하고, 그 다음 Apache HTTP Server를 거친 응답을 비교한다.
관련 블로그 기록
- LB·WAF 뒤에서 클라이언트 실제 IP 살리기 — 프록시 뒤에서 원래 클라이언트 정보를 보존한 사례
- NGINX 부하분산 (HTTP / TCP) — 다른 Web Server지만 upstream과 세션 관점이 비슷한 사례
공식 문서
닫기 전 질문
- Apache HTTP Server는 forward proxy가 아니라 reverse proxy로 설정되어 있는가?
- Tomcat HTTP Connector는 내부에서 정상 응답하는가?
- Host, scheme, client IP가 애플리케이션까지 전달되는가?
- timeout은 Apache, Tomcat, DB 중 어느 계층에서 먼저 발생하는가?