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_balancerBalancerMember 검토
오래된 AJP 기반 구성이 이미 있음mod_jkmod_proxy_ajp 문서도 함께 확인

새로 구성한다면 HTTP reverse proxy가 보통 이해하기 쉽다. 운영자가 curl로 Tomcat backend를 직접 확인할 수 있고, 설정도 ProxyPass 중심으로 읽힌다.

필요한 모듈

모듈역할
mod_proxy프록시 공통 기능
mod_proxy_httpHTTP backend 연결
mod_headersX-Forwarded-Proto 같은 헤더 설정
mod_sslHTTPS 종료가 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 의존도를 낮출 수 있다.

장애별 확인

증상확인 지점
502Tomcat 포트, firewall, ProxyPass URL, backend 기동 상태
503balancer member down, health check, worker 오류
redirect loopHTTPS 종료 위치, 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를 거친 응답을 비교한다.

관련 블로그 기록

공식 문서

닫기 전 질문

  • Apache HTTP Server는 forward proxy가 아니라 reverse proxy로 설정되어 있는가?
  • Tomcat HTTP Connector는 내부에서 정상 응답하는가?
  • Host, scheme, client IP가 애플리케이션까지 전달되는가?
  • timeout은 Apache, Tomcat, DB 중 어느 계층에서 먼저 발생하는가?