Java / / 2022. 5. 18. 18:02

Apache 로드밸런싱 + 세션 클러스터링

반응형

 

웹서버 하나만 사용하거나 WAS 하나만을 사용하며 웹 서비스를 운영하는 경우는 극히 드물다.

웹서버의 장점과 WAS의 장점 그 두 마리 토끼를 다 잡기 위해 보통 앞단에 웹서버를 두고 그 뒤에 WAS를 두며 서비스를 운영하고 있다. 하지만 운영하는 서비스의 유입이 늘어서 응답이 느려 서버를 늘려야 하는 상황이 생긴다고 가정해 보자.

 

원래 운영하던 서버들이 너무 좋아서 CPU나 메모리 사용률이 거의 바닥이어도 서버를 구매해야하는 것인가?

서버를 구매하면 결국 두개 이상의 서버가 운영될 텐데 그 서버들을 앞에서 묶어주며 트래픽을 분산시켜 주는 무언가가 필요하다. 그런 한 기술을 로드밸런싱이라고 한다. 

 

통상 L4스위치를 활용하여 여러 서버들로 분산시키며 산술적으로는 서버 대수만큼 성능이 좋아지는 효과를 볼 수 있다. 하지만 앞에서 말했듯 서버의 자원 사용률이 바닥일 정도로 거의 사용을 안 할 경우 서버를 구매하는 것은 너무 비효율 적이다. 서버를 늘리지 않으면서 웹서버 중 아파치를 활용하여 여러 WAS를 운영하는 방법에 대해서 포스팅하려고 한다.

 

▶ Apache 로드밸런싱

로드밸런싱이란?

WEB 서버와 WAS서버와 연동되어 있다해도 실제로 수행되는 작업들이 골고루 분산되지 않으면 제대로 활용하지 못하는데 이러한 문제를 해결하기 위해 작업을 균형 있게 분산시켜 주기 위해 로드밸런싱을 사용합니다.

 

아파치와 톰캣을 연동하는 이유

  • Tomcat 서버는 본연의 임무인 서블릿 컨테이너의 역할만 하고, Apache HTTP Server는 웹 서버의 역할을 하도록 각각의 기능을 분리하기 위해 연동을 할 수 있다.

 

연동원리

  • 아파치와 톰캣이 연동하기 위해선 AJP를 통해 서로 통신을 하여야 한다.
  • AJP란 아파치가 웹 서버와 외부 서비스(톰캣 등)과 연동하기 위해 정한 규약(프로토콜)이다.
  • 아파치는 이를 사용하여 80 포트로 들어오는 요청은 자신이 받고, 이 요청 중 서블릿을 필요로 하는 요청은 톰캣에 접속하여 처리한다.
    • 아파치 웹서버의 httpd.conf 에 톰캣 연동을 위한 설정을 추가하고 톰캣에서 처리할 요청을 지정
    • 사용자의 브라우저는 아파치 웹서버(보통 80 포트)에 접속해 요청
    • 아파치 웹 서버는 사용자의 요청이 톰캣에서 처리하도록 지정된 요청인지 확인. 요청을 톰캣에서 처리해야 하는 경우 아파치 웹 서버는 톰캣의 AJP포트(보통 8009 포트)에 접속해 요청을 전달
    • 톰캣은 아파치 웹 서버로부터 요청을 받아 처리한 후, 처리 결과를 아파치 웹서버에 되돌려줌
    • 아파치 웹 서버는 톰캣으로부터 받은 처리 결과를 사용자에게 전송

 

Httpd

  1. yum -y install httpd
    1. rpm -qa | grep httpd로 확인하시면 됩니다.
  2. 이제 서비스를 시작해 줍니다.
    1. systemctl start httpd
    2. systemctl enable httpd
  3. 방화벽 설정
    1. firewall-cmd --permanent --add-service=http // 서비스 추가
    2. firewall-cmd --permanent --add-port=80/tcp // 80번 포트 추가 (http가 주로 사용하는 포트)
    3. firewall-cmd --reload // 적용

 

Apache - Connector

  1. yum -y install gcc gcc-c++ httpd-devel 설치
  2. tar -zxvf tomcat-connectors-1.2.46-src.tar.gz 다운로드 후 압축 풀기
  3. $ cd tomcat-connectors-1.2.46-src/native 경로 이동
  4. $ find / -name apxs (경로 찾기)
  5. $ ./configure --with-apxs=/(찾은경로)/apache/bin/apxs
  6. $ make && make install 설치
  7. $ /home/~~~/apache/modules 하위에 mod_jk.so가 생김

 

 

Apache 설정

  1. 아파치 설정 1)
    1. /etc/httpd/conf/httpd.conf 열기
    2. ServerRoot 찾기
    3. 아래 코드처럼 변경
    Define SRVROOT "/etc/httpd"
    serverRoot "${SRVROOT}"
    
  2. 아파치 설정 2)
    1. /etc/httpd/conf/httpd.conf 열기
    2. ServerName 찾기
    3. ServerName localhost:80으로 변경
    #ServerName www.example.com:80
    ServerName localhost:80
    
  3. 아파치 설정 3)
    1. /etc/httpd/conf/httpd.conf 열기
    2. 맨 아래 다음 코드 작성
    방법 1.
    LoadModule jk_module modules/mod_jk.so
    <IfModule jk_module>
        JkWorkersFile   conf/workers.properties //워커설정파일 위치
        JkLogFile       logs/mod_jk.log //로그 위치, 위치도 변경가능
        JkLogLevel      info //로그레벨, 원하는 것으로 변경 가능
        JkMount /*      load_balancer //Apache에서 다른 웹 컨테이너(load_balancer)에게 맡길 파일 종류 작성
    </IfModule>
    
    방법 2.
    LoadModule jk_module modules/mod_jk.so 
    JkWorkersFile conf/workers.properties
    JkLogFile logs/mod_jk.log
    JkLogLevel debug
    JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
    JkMount /* loadbalancer
  4. 아파치 설정 4)
    1. 파일 경로 설정(올리고 싶은 홈페이지의 파일 경로를 설정해 주어야 함)
    2. /etc/httpd/conf/httpd.conf 열기
    3. Tomcat 안의 war파일을 풀고 그 경로를 적어준다.
    DocumentRoot "C:/tomcat7/webapps"
    <Directory "c:/tomcat7/webapps">
    

 

 

 

 

 

  1. 로드밸런싱 작업 1)
    1. /etc/httpd/conf/workers.properties 파일 생성
    2. 파일 생성 후 아래 코드 작성
worker.list=load_balancer

worker.load_balancer.type=lb
worker.load_balancer.balanced_workers=tomcat1,tomcat2 //tomcat서버를 구분할 수 있는 이름
worker.load_balancer.sticky_session=TRUE

worker.tomcat1.port=8009 // Tomcat AJP 포트
worker.tomcat1.host=127.0.0.1 //각 서버의 IP
worker.tomcat1.type=ajp13 //work type
worker.tomcat1.lbfactor=1 //부하분산 설정

worker.tomcat2.port=8009
worker.tomcat2.host=127.0.0.2
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=1
  • Tomcat의 웹 컨테이너 연결을 하는 것이다.
  • Tomcat안에 conf/server.xml에 들어가면 다음과 같은 내용이 있다.
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
  • 위의 내용을 아파치에 연결하는 것이다.

 

Tomcat 설정

  1. 로드밸런싱 작업 1)
    1. conf/server.xml 열기
    2. 해당 부분 변경
    <!-- Define an AJP 1.3 Connector on port 8009 -->
        <Connector protocol="AJP/1.3"
                   address="0.0.0.0"
                   port="8009"
                   redirectPort="8443"
                   secretRequired="false"/>
    
  2. 로드밸런싱 작업 2)
    1. Tomcat 1 (WAS1)
      1. conf/server.xml 열기
      2. 해당 부분 수정
      <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
      
    2. Tomcat 2 (WAS2)
      1. conf/server.xml 열기
      2. 해당 부분 수정
      <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
      
  3. 로드밸런싱 작업 3)
    1. 방화벽 해제필요
    2. 80, 8009 포트 해제
    firewall-cmd --permanent --zone=public --add-port=80/tcp
    firewall-cmd --permanent --zone=public --add-port=8009/tcp
    firewall-cmd --reload
    

참고 : Http 접속 포트 끄기 - Apache / Tomcat을 연동하고 나면 반드시 Tomcat 인스턴스의 Http 접속포트를 Disable 해주어야 한다. 하지 않으면 8080 포트로 접속이 가능하다.

<!--
	<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
-->

 

 

 

▶ 톰캣 세션 클러스터링

Tomcat 설정

  • conf/server.xml
  1. conf/server.xml 설정 파일 열기
  2. <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> 을 검색하면 주석처리가 되어 있는데, 해당 부분을 찾는다.
  3. 아래에 다음 코드를 추가(주석 밖)
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">

	<Manager className="org.apache.catalina.ha.session.BackupManager"
		expireSessionsOnShutdown="false"
		notifyListenersOnReplication="true"/>

	<Channel className="org.apache.catalina.tribes.group.GroupChannel">
		<Membership className="org.apache.catalina.tribes.membership.McastService"
			address="228.0.0.4"
			port="45564"
			frequency="500"
			dropTime="3000"/>

		<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
			<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
		</Sender>

		<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
			address="Tomcat IP" //해당 서버의 톰캣 ip
			port="4000" // 포트는 4000~4100으로 모두 다른 포트 사용 #tomcat2 4001 (+1 증가)
			autoBind="100"
			selectorTimeout="5000"
			maxThreads="6"/>

		<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
		<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>

	</Channel>

	<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
	<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

	<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
			tempDir="/tmp/war-temp/"
			deployDir="/tmp/war-deploy/"
			watchDir="/tmp/war-listen/"
			watchEnabled="false"/>

	<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
	<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
  • WAS1, WAS2 둘 다 설정을 해주어야 한다.
  • port는 4000~4100중 하나로 모두 다른 포트를 사용해야 한다.
  • 프로젝트 안 WEB-INF/web.xml
  • 주의 : Tomcat의 conf/web.xml이 아니다.
  • </web-app> 위에 <distributable/> 추가!
  • 방화벽 해제
  • 45564 tcp/udp 해제, 4000~4100/tcp 해제
firewall-cmd --permanent --zone=public --add-port=45564/tcp
firewall-cmd --permanent --zone=public --add-port=45564/udp
firewall-cmd --permanent --zone=public --add-port=4000-4100/tcp
firewall-cmd --reload

 

 

 

 

결과

 

▶ Tomcat 인스턴스를 모두 실행시킨 뒤 logs/catalina.out 에서 각각의 로그를 확인해서 아래와 같이 출력이 되면 Session Clustering 이 연결됐다는 의미입니다.

ex)

  • WAS01 (IP : 172.27.1.3)

17-May-2017 21:07:22.416 INFO [Membership-MemberAdded.] org.apache.catalina.ha.tcp.SimpleTcpCluster.memberAdded Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{172, 27, 0, 81}:4011,{172, 27, 0, 81},4011, alive=19538, securePort=-1, UDP Port=-1, id={35 -123 -62 23 10 -31 73 -5 -78 -89 2 -41 41 84 105 -57 }, payload={}, command={}, domain={}, ]

  • WAS02 (IP : 172.27.0.81)

17-May-2017 21:07:23.127 INFO [Membership-MemberAdded.] org.apache.catalina.ha.tcp.SimpleTcpCluster.memberAdded Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{172, 27, 1, 3}:4010,{172, 27, 1, 3},4010, alive=1019, securePort=-1, UDP Port=-1, id={-15 -5 -50 50 41 119 73 -57 -89 103 25 62 3 -100 -77 -108 }, payload={}, command={}, domain={}, ]

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유