아파치 웹 서버(apache httpd) 와 톰캣 연동하기 - tomcat connector(mod_jk) , reverse proxy(mod_proxy)
mod_jk 보다는 mod_proxy 를 사용하는 것이 설정도 간단하고 nginx 같은 차세대 웹 서버로 이전하기가 쉬우니 mod_proxy 사용을 권장합니다.
개요
Apache httpd web server 와 tomcat 을 연계하는 방법은 세 가지가 있다.
예전부터 많이 쓰던 방법은 tomcat connector(mod_jk)를 사용하는 방법이고 다른 하나는 mod_proxy를 사용하여 reverse proxy 기능을 사용하는 방법, 마지막은 mod_proxy_ajp 를 사용하여 AJP Protocol을 reverse proxy 로 사용하는 방법이다.
mod_proxy 가 mod_jk 에 비해 설정이 간편하고 AJP 같은 특정 WAS 의존적인 프로토콜을 사용하지 않으므로 성능이 더 좋다고 하지만 mod_jk 가 오랫동안 써왔고 친숙해서 mod_jk 를 많이 사용하는 편인데 세 가지 방법 모두 정리해 본다.
연결 방식 | 장점 | 단점 | 특징 |
---|---|---|---|
mod_jk |
|
| |
mod_proxy |
|
| |
mod_proxy_ajp |
|
| |
Tomcat Connector mod_jk
mod_jk compile
- RHEL6/CentOS 6 기준이며 compile 을 하려면 사전에 gcc 와 httpd-devel 패키지가 설치되어 있어야 한다. (yum install gcc gcc-c++ httpd-devel)
- mod_jk compile 이 귀찮으면 첨부되어 있는 pre-compiled connector 를 다운받은 후에/etc/httpd/moduels 에 복사해 준다.
- mod_jk_1.2.37-x86_64.tar.gz - RHEL6 64bit
- mod_jk_1.2.37-x86.tar.gz - RHEL6 32bit
- http://tomcat.apache.org/download-connectors.cgi 에서 소스 download (현재 1.2.37)
- tar zxvf tomcat-connectors-1.2.37-src.tar.gz
- cd tomcat-connectors-1.2.37-src/native
- ./configure --with-apxs=/usr/sbin/apxs
- make
- make install
make install 후 /etc/httpd/modules/mod_jk.so 에 복사가 된다.
SELinux 를 사용한다면 mod_jk.so 에 httpd_modules_t Context 가 설정되어야 apache httpd 가 읽을 수 있다. 다음 명령어로 설정하자.
chcon -u system_u -r object_r -t httpd_modules_t /etc/httpd/modules/mod_jk.so
Apache httpd 설정
- cd /etc/httpd
vim conf/httpd.conf
LoadModule jk_module modules/mod_jk.so
CODEvim conf.d/mod_jk.conf
<IfModule mod_jk.c> # Where to find workers.properties JkWorkersFile conf/workers_jk.properties # Where to put jk shared memory JkShmFile run/mod_jk.shm # Where to put jk logs JkLogFile logs/mod_jk.log # Set the jk log level [debug/error/info] JkLogLevel info # Select the timestamp log format JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " ## url pattern 에 따른 connector mapping ##JkMountFile conf/uriworkermap.properties </IfModule>
BASHvim conf/workers_jk.properties
tomcat 은 server1, server2 두 대에 설치되어 있고 Connector Port는 8009 라 가정
Tomcat의 AJP Connector 가 listen하는 Port는 tomat의 conf/server.xml 에서 다음 항목에서 확인할 볼 수 있다.
tomcat 은 기본 URIEncoding 이 ISO-8859-1 이므로 한글이 깨지므로 모든 커넥터 설정에 URIEncoding="UTF-8" 을 추가해야 한다.
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
XMLajp protocol connector 설정
worker.list=worker1, worker2 worker.worker1.port=8009 worker.worker1.host=server1 worker.worker1.type=ajp13 worker.worker1.lbfactor=1 ## server 2 worker.worker2.port=8009 worker.worker2.host=server2 worker.worker2.type=ajp13 worker.worker2.lbfactor=1
BASHvim conf/uriworkermap.properties - 어떤 url 요청에 대해 tomcat 과 연계할지 설정한다. (uriworkermap.properties configuration )
## Mapping the URI /service1 under worker1 /service1/*.do=worker1 /service1/*.jsp=worker1 # /service2 요청으로 들어온 것은 worker2 로 mount /service2/*=worker2 # png와 jpg 는 apache 가 처리 !/service2/*.png=worker2 !/service2/*.jpg=worker2
BASH## 아래와 같이 설정하면 모든 요청(jsp, do, image, js등)을 tomcat으로 보내서 처리한다. /*=worker1
BASH- service httpd restart
- Browser 로 연결하여 정상 동작 여부 확인
TroubleShooting
- SELinux 를 쓸 경우(서비스 서버라면 SELinux 사용을 적극 권장한다!) 문제가 발생할 때 다음 문서 참고
mod_proxy 사용
reverse proxy 로 동작하는 모듈이다. 보안상 문제가 있을 수 있으므로 reverse proxy 에 대해서 숙지한 후에 설정하는 것을 권장한다.
mod_proxy.so 와 mod_proxy_http.so 가 LoadModule 로 로딩해야 한다. (RHEL/CentOS 는 기본 로딩됨)
reverse proxy 로 사용할 경우 기본적으로 모든 clinet 가 연결 가능하므로 내부에서만 사용해야 하는 service등의 경우 적용시 access control 을 여부를 검토해야 한다.
설정 예
WAS IP 가 192.168.10.100이고 WebApp 이름이 mywebapp
- Web Server의 VirtualHost 이름은 dummy-host.example.com
httpd.conf
<VirtualHost *:80>
ServerName dummy-host.example.com
ErrorLog logs/dummy-host.example.com-error_log
CustomLog logs/dummy-host.example.com-access_log common
# Put this in the main section of your configuration (or desired virtual host, if using Apache virtual hosts)
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
## mywebapp 설정
ProxyPass /mywebapp http://192.168.10.100:8080/mywebapp
ProxyPassReverse /mywebapp http://192.168.10.100:8080/mywebapp
<Location /mywebapp>
Order allow,deny
Allow from all
</Location>
</VirtualHost>
- ProxyRequests - On 일 경우 Forward Proxy 로 동작하며 Off 일 경우 Reverse Proxy 이다.
ProxyPreserveHost - On 일 경우 HTTP 요청 헤더중 Host: 부분을 유지한다.
httpd는 /mywebapp/foo, /mywebapp/bar 모두 192.168.10.100:8080/mywebapp 에 연결하게 된다. 만약 특정 URL 패턴은 reverse proxy 로 동작하지 말아야 한다면 ProxyPassMatch 으로 URL 을 처리할 수 있다.
# /mywebapp/bar 하위의 URL 은 접근 금지
ProxyPassMatch ^/mywebapp/bar[^.]+ !
ProxyPass /mywebapp http://192.168.10.100/mywebapp
ProxyPass /mywebapp http://192.168.10.100/mywebapp
ProxyPassReverse /mywebapp http://192.168.10.100/mywebapp
<Location /mywebapp>
Order allow,deny
Allow from all
</Location>
SSL Proxy
SSL 일 경우 Proxy 기능이 꺼져 있다. SSL 프로토콜일때도 mod_proxy 를 사용하려면 가상 호스트 항목에 다음 내용을 추가해야 한다.
<VirtualHost _default_:443>
SSLProxyEngine on
</VirtualHost>
TODO
mod_proxy_balancer 적용예제 추가
mod_proxy_ajp 사용
AJP13 protocol을 사용해서 reverse proxy 로 동작하는 방식이다. http reverse proxy 와 비슷하지만 protocol 을 ajp 로 적어주면 된다.
ProxyPass /app ajp://backend.example.com:8009/app
같이 보기
- 포워드 프록시(forward proxy) 리버스 프록시(reverse proxy) 의 차이
- Java Web Application Server(tomcat, jetty, JBoss 등)