mod_jk 설정 — 설치부터 JkMount까지
mod_jk는 레거시 Apache+Tomcat 연동의 표준 방식이었습니다. 현재는 새 프로젝트에 권장하지 않지만, 기존 시스템 유지보수를 위해 설정 방법을 이해할 필요가 있습니다.
mod_jk 설치
Ubuntu/Debian
# APT로 설치 (가장 간단)
sudo apt install libapache2-mod-jk
# 설치 확인
apache2ctl -M | grep jk
# jk_module (shared)
CentOS/RHEL
# EPEL 저장소 필요
sudo dnf install epel-release
sudo dnf install mod_jk
# 모듈 파일 위치
ls /etc/httpd/modules/mod_jk.so
소스 컴파일 (최신 버전)
# 의존성
sudo apt install -y build-essential apache2-dev
# 소스 다운로드
cd /tmp
wget https://dlcdn.apache.org/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.49-src.tar.gz
tar -xzf tomcat-connectors-1.2.49-src.tar.gz
cd tomcat-connectors-1.2.49-src/native
# 컴파일
./configure --with-apxs=/usr/bin/apxs
make
sudo make install
# 확인
ls /usr/lib/apache2/modules/mod_jk.so
workers.properties 설정
workers.properties는 mod_jk의 핵심 설정 파일로, Tomcat 인스턴스(워커)를 정의합니다.
# /etc/apache2/workers.properties
# === 단일 Tomcat 워커 ===
worker.list=worker1
# 워커 타입: ajp13 (AJP/1.3)
worker.worker1.type=ajp13
worker.worker1.host=127.0.0.1
worker.worker1.port=8009
# 연결 설정
worker.worker1.connection_pool_size=10 # 연결 풀 크기
worker.worker1.connection_pool_timeout=600 # 유휴 연결 타임아웃(초)
worker.worker1.socket_timeout=300 # 소켓 타임아웃(초)
worker.worker1.socket_keepalive=true # TCP keepalive
# 재시도 설정
worker.worker1.retries=2
worker.worker1.recovery_options=7 # 오류 시 자동 복구
로드밸런싱 워커 설정
# /etc/apache2/workers.properties
# 개별 Tomcat 인스턴스
worker.list=lb_worker,tomcat1,tomcat2
worker.tomcat1.type=ajp13
worker.tomcat1.host=127.0.0.1
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.lb_worker.type=lb
worker.lb_worker.balance_workers=tomcat1,tomcat2
worker.lb_worker.method=R # R=Round Robin, T=Traffic, B=Busyness
worker.lb_worker.sticky_session=true # 세션 고정 활성화
worker.lb_worker.sticky_session_force=false # 실패 시 다른 노드로 전환
Apache 설정 — mod_jk 로드 및 JkMount
# /etc/apache2/conf-available/mod-jk.conf
# 모듈 로드
LoadModule jk_module /usr/lib/apache2/modules/mod_jk.so
# workers.properties 경로
JkWorkersFile /etc/apache2/workers.properties
# 로그 설정
JkLogFile /var/log/apache2/mod_jk.log
JkLogLevel warn # info, warn, error
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
# 요청/응답 로그 (디버깅용, 프로덕션에서 비활성화)
JkRequestLogFormat "%w %V %T"
# 설정 활성화
sudo a2enconf mod-jk
sudo systemctl reload apache2
VirtualHost에서 JkMount 사용
# /etc/apache2/sites-available/myapp.conf
<VirtualHost *:80>
ServerName example.com
# 모든 요청을 worker1으로 전달
JkMount /* worker1
# 정적 파일은 Apache가 직접 서빙 (JkUnMount)
JkUnMount /static/* worker1
JkUnMount /images/* worker1
JkUnMount /css/* worker1
JkUnMount /js/* worker1
# 정적 파일 디렉터리
Alias /static /var/www/myapp/static
<Directory "/var/www/myapp/static">
Options -Indexes
Require all granted
</Directory>
# 액세스 로그
CustomLog ${APACHE_LOG_DIR}/myapp_access.log combined
ErrorLog ${APACHE_LOG_DIR}/myapp_error.log
</VirtualHost>
세션 고정(Sticky Session) 설정
클러스터 환경에서 같은 클라이언트는 항상 같은 Tomcat 인스턴스로 라우팅되도록 합니다.
Tomcat server.xml 설정
<!-- 각 Tomcat 인스턴스에 고유한 jvmRoute 설정 -->
<!-- Tomcat 1: server.xml -->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
<!-- Tomcat 2: server.xml -->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
workers.properties 세션 고정
worker.lb_worker.sticky_session=true
# JSESSIONID 예시: abc123.tomcat1 (마지막 .tomcat1이 라우팅 키)
# worker.worker1.route=tomcat1 (명시적 라우팅 키)
worker.tomcat1.route=tomcat1
worker.tomcat2.route=tomcat2
mod_jk 상태 페이지
mod_jk의 상태 페이지에서 워커 상태, 로드밸런싱 통계를 실시간으로 확인할 수 있습니다.
<VirtualHost *:80>
ServerName admin.example.com
# mod_jk 상태 페이지
<Location /jkstatus>
JkMount jkstatus
Require ip 127.0.0.1 192.168.1.0/24
</Location>
</VirtualHost>
workers.properties에 상태 워커 추가:
worker.list=worker1,jkstatus
worker.jkstatus.type=status
worker.jkstatus.read_only=true # 읽기 전용 (보안)
# 상태 페이지 접근 (내부망에서만)
curl http://localhost/jkstatus/
mod_jk → mod_proxy_http 마이그레이션
레거시 mod_jk에서 mod_proxy_http로 전환하는 단계별 가이드입니다.
1단계: Tomcat HTTP 커넥터 확인
<!-- server.xml — HTTP 커넥터가 있는지 확인 -->
<Connector port="8080" protocol="HTTP/1.1"
address="127.0.0.1"
connectionTimeout="20000"/>
2단계: Apache 설정 변경
# 기존 mod_jk 방식 (제거)
# JkMount /* worker1
# 신규 mod_proxy_http 방식
<VirtualHost *:80>
ServerName example.com
ProxyRequests Off
ProxyPreserveHost On
# 정적 파일 제외
ProxyPass /static !
ProxyPass /images !
# 동적 요청 전달
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>
3단계: AJP 커넥터 비활성화 (보안)
<!-- server.xml — AJP 커넥터 주석 처리 -->
<!--
<Connector protocol="AJP/1.3"
address="127.0.0.1"
port="8009"
redirectPort="8443"/>
-->
문제 진단
# mod_jk 로그 확인
tail -f /var/log/apache2/mod_jk.log
# 일반적인 에러
# [warn] ajp_get_reply::jk_ajp_common.c: Timeout waiting for a reply
# 워커 상태 CLI 확인
# curl -s "http://localhost/jkstatus/?cmd=show&w=worker1"
# AJP 포트 확인
ss -tlnp | grep 8009
# mod_jk 로그 레벨 임시 증가 (디버깅)
# JkLogLevel debug (httpd.conf에서 변경 후 reload)
Summary
| 항목 | 설정 위치 | 내용 |
|---|---|---|
| 모듈 로드 | httpd.conf | LoadModule jk_module ... |
| 워커 정의 | workers.properties | ajp13 타입, host, port |
| URL 매핑 | VirtualHost | JkMount /* worker1 |
| 정적 제외 | VirtualHost | JkUnMount /static/* worker1 |
| 세션 고정 | workers.properties + server.xml | jvmRoute + sticky_session=true |
| 마이그레이션 | — | mod_proxy_http로 전환 권장 |