본문 바로가기

프로그램/WAS, Infra

Apache + Tomcat 연동

실제 프로젝트에서는 대부분 Web서버와 Was 서버를 분리하여 운영 합니다.

Web 서버는 대부분 Apache를 사용하고 Was 서버는 웹로직, 웹스피어, 제우스, 톰켓 등등을 사용 합니다.

여러가지 was 중에서 톰켓은 무료로 사용 할수 있습니다. 그래서 규모가 작은 곳에서는 tomcat을 사용합니다.
규모가 작다는 것은 Money가 없다는 것일뿐 톰켓 성능이 안좋다는 것은 아닙니다.

비용을 지불하고 사용하는 was의 경우는 기술지원 및 초기 셋팅을 해주기 때문에 개발자가 할일이 없으나 비용을 지불하지 않는 톰켓의 경우는 별다른 기술지원을 받을수가 없습니다.

즉, 개발자 혹은 프로젝트의 누군가가 직접 셋팅을 해야할 경우가 많다는 겁니다.

Tomcat 셋팅에 대해 알아두어야 하는 이유가 위와 같습니다.
그럼 왜 web서버와 was서버를 분리 할까요?

두가지 측면에서 효용서이 있습니다.

1. 보안적인 측면
web 서버를 인터넷 망에 연결하고 was를 방화벽 안쪽에 두어 외부사용자가 web 서버를 통하지 않고는 내부망에 접근하지 못하도록 합니다.

2. 성능적인 측면
일반적으로 static resource 들(이미지, js파일등)을 web서버에서 처리하고, 기타 프로그그램 처리 결과만을 was에서 처리후 반환하도록 하여 was 부하를 줄일 수 있고 사용자 응답 속도를 증가 실킬 수 있습니다.

구글에서 apache tomcat 연동 으로 검색하면 많은 글들이 나오는데..
이중에서
https://www.lesstif.com/pages/viewpage.action?pageId=12943367
에 나온 글이 괜찮게 보입니다.

위 링크에 나온글 중에서 몽실이네는 apache의 mod_jk 모듈을 사용하는 방법을 쓰기로 합니다.

데비안 기준으로 apache2의 설정파일 경로는 아래와 같습니다.


pi@raspberrypi:/etc/apache2 $ ls -al
합계 96
drwxr-xr-x   8 root root  4096  9월  2 16:28 .
drwxr-xr-x 129 root root 12288 11월 14 09:59 ..
-rw-r--r--   1 root root  7217  9월  2 16:28 apache2.conf
drwxr-xr-x   2 root root  4096  9월  1 13:35 conf-available
drwxr-xr-x   2 root root  4096  9월  1 13:35 conf-enabled
-rw-r--r--   1 root root  1782  4월  6  2018 envvars
-rw-r--r--   1 root root 31063  9월 20  2017 magic
drwxr-xr-x   2 root root 12288 10월 22 17:42 mods-available
drwxr-xr-x   2 root root  4096 10월 22 17:43 mods-enabled
-rw-r--r--   1 root root   320  9월 20  2017 ports.conf
drwxr-xr-x   2 root root  4096 11월 14 15:42 sites-available
drwxr-xr-x   2 root root  4096 11월 14 15:42 sites-enabled

예전에는 한 파일에서 모두 셋팅했는데 이제는 각 기능별로 다 나눠져 있네요.
xxx-available 폴더에는 설정 가능한 예시 들이 있고
xxx-enabled 폴더에는 실제로 사용하는 설정 들이 있습니다.
xxx-enabled 폴더내의 파일은 대부분이 심볼릭 링크로 만들어져 있습니다.

mods-enabled 폴더에 windhome-jk.conf라는 파일을 만들었습니다.
아래는 파일의 내용 입니다.


# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Configuration Example for mod_jk
# used in combination with Apache 2.2.x

<IfModule jk_module>

    # We need a workers file exactly once
    # and in the global server
    JkWorkersFile /etc/libapache2-mod-jk/workers.properties

    # Our JK error log
    # You can (and should) use rotatelogs here
    JkLogFile /var/www/logs/mod_jk.log

    # Our JK log level (trace,debug,info,warn,error)
    JkLogLevel info

    # Our JK shared memory file
    JkShmFile /var/www/logs/jk-runtime-status

    # Define a new log format you can use in any CustomLog in order
    # to add mod_jk specific information to your access log.
    # LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Cookie}i\" \"%{Set-Cookie}o\" %{pid}P %{t
id}P %{JK_LB_FIRST_NAME}n %{JK_LB_LAST_NAME}n ACC %{JK_LB_LAST_ACCESSED}n ERR %{JK_LB_LAST_ERRORS}n BSY %{JK_LB_LAST_BUSY}n
 %{JK_LB_LAST_STATE}n %D" extended_jk

    # This option will reject all requests, which contain an
    # encoded percent sign (%25) or backslash (%5C) in the URL
    # If you are sure, that your webapp doesn't use such
    # URLs, enable the option to prevent double encoding attacks.
    # Since: 1.2.24
    # JkOptions +RejectUnsafeURI

    # This option will collapse multiple adjacent slashes
    # in request URLs before looking for mount or unmount
    # matches.
    # Since: 1.2.41
    # JkOptions +CollapseSlashesAll

    # After setting JkStripSession to "On", mod_jk will
    # strip all ";jsessionid=..." from request URLs it
    # does *not* forward to a backend.
    # This is useful, if all links in a webapp use
    # URLencoded session IDs and parts of the static
    # content should be delivered directly by Apache.
    # Of course you can also do it with mod_rewrite.
    # Since: 1.2.21
    # JkStripSession On

    # Start a separate thread for internal tasks like
    # idle connection probing, connection pool resizing
    # and load value decay.
    # Run these tasks every JkWatchdogInterval seconds.
    # Since: 1.2.27
    JkWatchdogInterval 60

    # Configure access to jk-status and jk-manager
    # If you want to make this available in a virtual host,
    # either move this block into the virtual host
    # or copy it logically there by including "JkMountCopy On"
    # in the virtual host.
    # Add an appropriate authentication method here!
    <Location /jk-status>
        # Inside Location we can omit the URL in JkMount
        JkMount jk-status
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1
    </Location>
    <Location /jk-manager>
        # Inside Location we can omit the URL in JkMount
        JkMount jk-manager
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1
    </Location>

    # If you want to put all mounts into an external file
    # that gets reloaded automatically after changes
    # (with a default latency of 1 minute),
    # you can define the name of the file here.
    # JkMountFile conf/extra/uriworkermap.properties

    # Example for Mounting a context to the worker "balancer"
    # The URL syntax "a|b" instantiates two mounts at once,
    # the first one is "a", the second one is "ab".
    # JkMount /myapp|/* balancer

    # Example for UnMounting requests for all workers
    # using a simple URL pattern
    # Since: 1.2.26
    # JkUnMount /myapp/static/* *

    # Example for UnMounting requests for a named worker
    # JkUnMount /myapp/images/* balancer

    # Example for UnMounting requests using regexps
    # SetEnvIf REQUEST_URI "\.(htm|html|css|gif|jpg|js)$" no-jk

    # Example for setting a reply timeout depending on the request URL
    # Since: 1.2.27
    # SetEnvIf Request_URI "/transactions/" JK_REPLY_TIMEOUT=600000

    # Example for disabling reply timeouts for certain request URLs
    # Since: 1.2.27
    # SetEnvIf Request_URI "/reports/" JK_REPLY_TIMEOUT=0

    # IMPORTANT: Mounts and virtual hosts
    # If you are using VirtualHost elements, you
    # - can put mounts only used in some virtual host into its VirtualHost element
    # - can copy all global mounts to it using "JkMountCopy On" inside the VirtualHost
    # - can copy all global mounts to all virtual hosts by putting
    #   "JkMountCopy All" into the global server
    # Since: 1.2.26

</IfModule>

site-enabled 디렉토리에는 버츄얼 호스트 관련 설정을 넣으면 됩니다.
몽실이네는 이미 ssl 설정이 되어 있어서 443 포트에 대한 셋팅이 되어 있습니다.

아래는 몽실이네 site.conf 내용 입니다.


<VirtualHost *:443>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        JkMount /* tomcat8
        #SetEnvIf Request_URI "/resources/*" no-jk

        #ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog /var/www/ssl-logs/error.log
        CustomLog /var/www/ssl-logs/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf


    SSLEngine on
    SSLProtocol all -SSLv2 -SSLv3
    SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256
-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA2
56:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE
-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:D
HE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CB
C3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA

    SSLHonorCipherOrder on

    SSLCertificateFile "/etc/letsencrypt/live/withwind.iptime.org/cert.pem"
    SSLCertificateKeyFile "/etc/letsencrypt/live/withwind.iptime.org/privkey.pem"
    SSLCertificateChainFile "/etc/letsencrypt/live/withwind.iptime.org/chain.pem"
</VirtualHost>

중요한 부부은
JkMount /* loadballance 입니다.

/* -> 즉 모든 요청에 대해서 loadballance 라는 worker 이름으로 처리한다는 겁니다.
--> 몽실이네는 static resource에 대해서도 was에서 처리 합니다.

그럼 저 loadballance 라는 워커는 어디에 정의되어 있을까요?

위에 windhome-jk.conf 파일의 내용중에서

JkWorkersFile /etc/libapache2-mod-jk/workers.properties
이런 부분이 있었습니다.
워커 설정 파일의 위치 입니다.

아래는 workers.properties의 내용 입니다.

# workers.properties -
#
# This file is a simplified version of the workers.properties supplied
# with the upstream sources. The jni inprocess worker (not build in the
# debian package) section and the ajp12 (deprecated) section are removed.
#
# As a general note, the characters $( and ) are used internally to define
# macros. Do not use them in your own configuration!!!
#
# Whenever you see a set of lines such as:
# x=value
# y=$(x)\something
#
# the final value for y will be value\something
#
# Normaly all you will need to do is un-comment and modify the first three
# properties, i.e. workers.tomcat_home, workers.java_home and ps.
# Most of the configuration is derived from these.
#
# When you are done updating workers.tomcat_home, workers.java_home and ps
# you should have 3 workers configured:
#
# - An ajp13 worker that connects to localhost:8009
# - A load balancer worker
#
#

# OPTIONS ( very important for jni mode )

#
# workers.tomcat_home should point to the location where you
# installed tomcat. This is where you have your conf, webapps and lib
# directories.
#
workers.tomcat_home=/usr/share/tomcat8

#
# workers.java_home should point to your Java installation. Normally
# you should have a bin and lib directories beneath it.
#
workers.java_home=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt

#
# You should configure your environment slash... ps=\ on NT and / on UNIX
# and maybe something different elsewhere.
#
ps=/

#
#------ ADVANCED MODE ------------------------------------------------
#---------------------------------------------------------------------
#

#
#------ worker list ------------------------------------------
#---------------------------------------------------------------------
#
#
# The workers that your plugins should create and work with
#
worker.list=tomcat8

#
#------ ajp13_worker WORKER DEFINITION ------------------------------
#---------------------------------------------------------------------
#

#
# Defining a worker named ajp13_worker and of type ajp13
# Note that the name and the type do not have to match.
#
worker.tomcat8.port=8009
worker.tomcat8.host=localhost
worker.tomcat8.type=ajp13
#
# Specifies the load balance factor when used with
# a load balancing worker.
# Note:
#  ----> lbfactor must be > 0
#  ----> Low lbfactor means less work done by the worker.
#worker.tomcat8.lbfactor=1

#
# Specify the size of the open connection cache.
#worker.tomcat8.cachesize

#
#------ DEFAULT LOAD BALANCER WORKER DEFINITION ----------------------
#---------------------------------------------------------------------
#

#
# The loadbalancer (type lb) workers perform wighted round-robin
# load balancing with sticky sessions.
# Note:
#  ----> If a worker dies, the load balancer will check its state
#        once in a while. Until then all work is redirected to peer
#        workers.
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=tomcat8

work.list에 tomcat8 하나만 설정되어 있습니다.
리스트에 추가하고 각각의 worker에 대한 설정을 달리하여 다른 서버에 있는 tomcat was와 연결 할 수도 있습니다.



현재 몽실이네는 라즈비안 OS 와, 우분투 OS에서 이중화 되어 운영되고 있습니다.

위 셋팅은 라즈비안에서만 서비스 하는 형태 입니다.
이제 우분투에서 구동되는 was를 연결해 보겠습니다.

우선 site.conf 파일에서 사용할 worker 이름을 바꿔 줍니다.

JkMount /* tomcat8
이것을
JkMount /* loadballance
로..



workers.properties 파일에
워커를 추가 합니다.

아래는 새롭게 설정한 내용 입니다.


workers.tomcat_home=/usr/share/tomcat8
workers.java_home=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt
ps=/

worker.list=pi,zbox,loadballance
worker.pi.type=ajp13
worker.pi.host=localhost
worekr.pi.port=8009
worker.pi.lbfactor=50
worker.pi.socket_timeout=1800  # 30분
worker.pi.socket_keepalive=1     # 사용:1, 미사용:0
worker.pi.connection_pool_timeout=600

worker.zbox.type=ajp13
worker.zbox.host=192.168.0.19
worker.zbox.port=8009
worker.zbox.lbfactor=100
worker.zbox.socket_timeout=1800  # 30분
worker.zbox.socket_keepalive=1     # 사용:1, 미사용:0
worker.zbox.connection_pool_timeout=600


# tomcat timeout에 따른 중복 발생 방지
worker.loadballance.retries=0
worker.pi.retries=0
worker.zbox.retries=0


worker.loadballance.type=lb

# sticky방식은 일정 시간(session time)동안 한 WAS에 지속적으로 접속하는 설정임
# 사용: true OR 1, 미사용: false OR 0

worker.loadballance.sticky_session=1
worker.loadballance.balanced_workers=pi,zbox


# configure jk-status
worker.list=jk-status
worker.jk-status.type=status
worker.jk-status.read_only=true
# configure jk-manager
worker.list=jk-manager
worker.jk-manager.type=status

워커 이름으로 pi,zbox,loadballance 이렇게 3개가 등록되었습니다.

각각의 이름에 해당한느 was정보가 셋티되어 있고요.

loadballance는 타입이 lb (로드벨러스 타입) 입니다.

JkMount 에서 loadballance로 셋팅했고..
worker.loadballance.balanced_workers=pi,zbox
에 의해서 pi, zbox로 분배되어 접속 됩니다.

pi의 host는 localhost 임으로 apache와 같은 머신에서 돌아간다는 것을 알수 있습니다.
zbox의 host는 ip를 직접 적어주었습니다.

둘다 tomcat의 ajp 포트는 같습니다.

아파치를 띄우고 접속해 보았습니다.


제목에 몽실이네집 2로 된것이 zbox에서 돌아가는 겁니다.



이번에는 pi에 붙었습니다.



다음에는 세션 클러스터링 셋팅을 해보겠습니다.

'프로그램 > WAS, Infra' 카테고리의 다른 글

apache 2.x + openssl 설치시 오류 해결 방법  (0) 2019.01.22