Skip to main content

Apache + Tomcat Integration

mod_jk, mod_proxy, AJP 기반 Apache-Tomcat 연동


📚 시리즈 네비게이션

이전현재다음
Apache vs NginxApache + TomcatNginx + Tomcat

시리즈 목차


🎯 왜 연동하는가?

Tomcat 단독으로도 서비스 가능하지만, Apache를 앞에 두는 이유:

이유설명
정적 파일 처리Apache가 정적 파일 처리에 효율적
SSL 종료Apache에서 SSL 처리, Tomcat은 HTTP만
로드밸런싱다중 Tomcat 분산
보안Tomcat 직접 노출 방지
URL Rewritemod_rewrite 활용
가상 호스트여러 도메인 처리

🔌 연동 방식 비교

방식프로토콜특징권장
mod_jkAJP전통적, 설정 복잡
mod_proxy_ajpAJPmod_proxy + AJP
mod_proxy_httpHTTP간단, 범용적

AJP vs HTTP

항목AJPHTTP
프로토콜바이너리텍스트
성능약간 빠름약간 느림
설정복잡간단
디버깅어려움쉬움 (tcpdump 가능)
방화벽8009 포트8080 포트
보안취약점 이슈 있었음상대적 안전

권장: 최근에는 mod_proxy_http를 더 많이 사용. AJP는 레거시 환경에서 주로 사용함.


⚙️ 방법 1: mod_jk (레거시)

개요

mod_jk는 Apache Tomcat Connector 프로젝트의 일부로, AJP 프로토콜로 통신함.

설치

# CentOS/RHEL
yum install mod_jk

# Ubuntu/Debian
apt install libapache2-mod-jk

# 또는 소스 컴파일
# https://tomcat.apache.org/connectors-doc/

Tomcat 설정 (server.xml)

AJP Connector 활성화:

<!-- $CATALINA_HOME/conf/server.xml -->
<Connector port="8009"
protocol="AJP/1.3"
redirectPort="8443"
secretRequired="false"
address="127.0.0.1" />

⚠️ 보안: address="127.0.0.1"로 로컬만 허용하거나, secret 설정 필요.

Apache 설정

workers.properties:

# /etc/httpd/conf/workers.properties

# Worker 목록
worker.list=tomcat1

# Worker 설정
worker.tomcat1.type=ajp13
worker.tomcat1.host=127.0.0.1
worker.tomcat1.port=8009
worker.tomcat1.lbfactor=1

httpd.conf 또는 가상호스트:

# mod_jk 로드
LoadModule jk_module modules/mod_jk.so

# workers.properties 위치
JkWorkersFile /etc/httpd/conf/workers.properties

# 로그 설정
JkLogFile /var/log/httpd/mod_jk.log
JkLogLevel info

# URL 매핑
JkMount /*.jsp tomcat1
JkMount /api/* tomcat1
JkMount /app/* tomcat1

# 정적 파일은 Apache가 처리 (매핑하지 않음)
# /images, /css, /js 등

uriworkermap.properties (선택):

# /etc/httpd/conf/uriworkermap.properties

# Tomcat으로 보낼 요청
/*.jsp=tomcat1
/api/*=tomcat1
/app/*=tomcat1

# Apache가 처리 (제외)
!/images/*=tomcat1
!/css/*=tomcat1
!/js/*=tomcat1
!/*.html=tomcat1
# httpd.conf에 추가
JkMountFile /etc/httpd/conf/uriworkermap.properties

로드밸런싱 (mod_jk)

# workers.properties

# Worker 목록 (로드밸런서 + 실제 워커들)
worker.list=loadbalancer

# Tomcat 인스턴스들
worker.tomcat1.type=ajp13
worker.tomcat1.host=192.168.1.10
worker.tomcat1.port=8009
worker.tomcat1.lbfactor=1

worker.tomcat2.type=ajp13
worker.tomcat2.host=192.168.1.11
worker.tomcat2.port=8009
worker.tomcat2.lbfactor=1

# 로드밸런서
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=tomcat1,tomcat2
worker.loadbalancer.sticky_session=true
# httpd.conf
JkMount /* loadbalancer

⚙️ 방법 2: mod_proxy_ajp

개요

Apache 기본 mod_proxy를 사용하여 AJP 연동. mod_jk보다 설정이 간단함.

Apache 설정

# 모듈 로드
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

<VirtualHost *:80>
ServerName example.com

# 정적 파일은 Apache가 처리
DocumentRoot /var/www/html

# 동적 요청은 Tomcat으로
ProxyPass /api ajp://127.0.0.1:8009/api
ProxyPassReverse /api ajp://127.0.0.1:8009/api

ProxyPass /app ajp://127.0.0.1:8009/app
ProxyPassReverse /app ajp://127.0.0.1:8009/app
</VirtualHost>

로드밸런싱 (mod_proxy_ajp)

<Proxy balancer://tomcat-cluster>
BalancerMember ajp://192.168.1.10:8009 route=tomcat1
BalancerMember ajp://192.168.1.11:8009 route=tomcat2
ProxySet lbmethod=byrequests
ProxySet stickysession=JSESSIONID
</Proxy>

<VirtualHost *:80>
ServerName example.com

ProxyPass / balancer://tomcat-cluster/
ProxyPassReverse / balancer://tomcat-cluster/
</VirtualHost>

⚙️ 방법 3: mod_proxy_http (권장)

개요

HTTP 프로토콜로 연동. 가장 간단하고 범용적임.

Tomcat 설정

HTTP Connector만 있으면 됨 (기본 활성화):

<!-- $CATALINA_HOME/conf/server.xml -->
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

Apache 설정

# 모듈 로드
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html

# Proxy 설정
ProxyPreserveHost On
ProxyRequests Off

# 동적 요청 → Tomcat
ProxyPass /api http://127.0.0.1:8080/api
ProxyPassReverse /api http://127.0.0.1:8080/api

ProxyPass /app http://127.0.0.1:8080/app
ProxyPassReverse /app http://127.0.0.1:8080/app

# 정적 파일은 Apache에서 직접 처리
<Directory /var/www/html>
Require all granted
</Directory>
</VirtualHost>

전체 요청 프록시

<VirtualHost *:80>
ServerName example.com

ProxyPreserveHost On
ProxyRequests Off

# 정적 파일 제외
ProxyPassMatch ^/images !
ProxyPassMatch ^/css !
ProxyPassMatch ^/js !

# 나머지는 Tomcat으로
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/

# 정적 파일 위치
Alias /images /var/www/static/images
Alias /css /var/www/static/css
Alias /js /var/www/static/js
</VirtualHost>

로드밸런싱 (mod_proxy_http)

<Proxy balancer://tomcat-cluster>
BalancerMember http://192.168.1.10:8080 route=tomcat1
BalancerMember http://192.168.1.11:8080 route=tomcat2
ProxySet lbmethod=byrequests
ProxySet stickysession=JSESSIONID
</Proxy>

<VirtualHost *:80>
ServerName example.com

ProxyPreserveHost On

ProxyPass / balancer://tomcat-cluster/
ProxyPassReverse / balancer://tomcat-cluster/
</VirtualHost>

로드밸런싱 알고리즘:

lbmethod설명
byrequests요청 수 기반 (기본)
bytraffic트래픽 양 기반
bybusyness활성 요청 수 기반
heartbeat하트비트 기반

🔒 SSL 설정

Apache에서 SSL 종료

<VirtualHost *:443>
ServerName example.com

# SSL 설정
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/server.crt
SSLCertificateKeyFile /etc/pki/tls/private/server.key
SSLCertificateChainFile /etc/pki/tls/certs/chain.crt

# Tomcat으로 프록시 (HTTP)
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/

# 헤더 추가 (Tomcat이 HTTPS임을 인식)
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</VirtualHost>

# HTTP → HTTPS 리다이렉트
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>

Tomcat 설정 (프록시 인식)

<!-- server.xml의 Connector -->
<Connector port="8080"
protocol="HTTP/1.1"
proxyName="example.com"
proxyPort="443"
scheme="https"
secure="true" />

또는 RemoteIpValve 사용:

<!-- server.xml의 Engine 또는 Host 내부 -->
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto" />

🩺 트러블슈팅

연결 안 됨

# Tomcat 포트 확인
netstat -tlnp | grep 8080
netstat -tlnp | grep 8009

# Tomcat 로그 확인
tail -f $CATALINA_HOME/logs/catalina.out

# Apache 에러 로그
tail -f /var/log/httpd/error_log

503 Service Unavailable

  • Tomcat이 실행 중인지 확인
  • 방화벽 확인: firewall-cmd --list-all
  • SELinux 확인: setsebool -P httpd_can_network_connect 1

AJP 연결 문제

# AJP 포트 확인
telnet 127.0.0.1 8009

# Tomcat 9+ AJP 보안 설정 확인
# secretRequired="false" 또는 secret 설정 필요

타임아웃

# Apache에서 타임아웃 늘리기
ProxyTimeout 300
Timeout 300

# 또는 ProxyPass에서
ProxyPass / http://127.0.0.1:8080/ timeout=300

세션 유지 안 됨 (로드밸런싱)

Tomcat의 jvmRoute 설정:

<!-- server.xml -->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
# Apache에서 route 매칭
BalancerMember http://192.168.1.10:8080 route=tomcat1

📋 설정 체크리스트

항목확인
Tomcat Connector 활성화 (8080 또는 8009)
Apache 모듈 로드 (mod_proxy, mod_proxy_http)
방화벽 포트 허용
SELinux 설정 (httpd_can_network_connect)
ProxyPreserveHost 설정
SSL 사용 시 X-Forwarded-Proto 헤더
로드밸런싱 시 sticky session

🔗 시리즈 네비게이션

이전다음
Apache vs NginxNginx + Tomcat Integration

시리즈 목차로 돌아가기


🔗 참고 자료