JBoss EAP 6과 친해지기 19탄 - 클러스터링 #1
본문 바로가기
IT 이야기/JBoss EAP

JBoss EAP 6과 친해지기 19탄 - 클러스터링 #1

by 찬찬이 아빠 2020. 12. 24.
반응형
  1. 클러스터링 이해

클러스터(Cluster)네트워크를 이요하여 마치 하나의 컴퓨터처럼 동작하도록 여러 대의 컴퓨터를 연결하여 구성하는 것을 말합니다. 즉, 여러 대의 서버들 전체를 한 대의 서버 시스템과 같이 동작하게 하는 기술이나 기능을 말합니다.

 

클라이언트 입장에서는 특정 서버의 상태에 의존하지 않고 클러스터로 묶인 서버 그룹을 마치 하나의 서버에서 서비스를 제공하는 것으로 인식합니다. 클러스터 내의 어떤 서버로 접속하든지 동일하게 처리되기 때문에 클라이언트의 요청을 클러스터 멤버에 분산하여 처리하는 것입니다. 이렇게 처리함으로써 클라이언트는 여러 개의 서버를 묶은 클러스터가 마치 하나의 서버인 것처럼 보이게 됩니다.

 

확장성과 고가용성이 요구되는 웹 시스템에서는 각각의 레이어마다 고유의 클러스터링 기술을 사용하고 있습니다. JBoss EAP 6를 사용한 웹 시스템 구축에서도 로드 밸런싱과 페일오버(failover)를 위해서 클러스터링 기능을 사용합니다. JBoss는 Java 프로세스 단위로 클러스터링을 구성하며, 서버의 물리적인 위치와 관계없이 구성이 가능합니다.

 

특히 고가용성이 요구되는 미션 크리티컬 업무에서 클러스터링은 매우 중요합니다. 예들 들어 금융권에서의 인터넷 뱅킹 시스템, 제조업에서 생산공정관리 시스템, 온라인 쇼핑몰 시스템 등의 서비스에서 클러스터를 이용하여 마치 하나의 서버에서 제공하는 것처럼 구성합니다. 클러스터링을 통해 특정 서버 장애가 전체 서비스에 영향을 마치지 않도록 구성하는 것이 매우 중요합니다.

 

클러스터를 구성하는 목적은 크게 두 가지로 부하 분산(Load Balancing)과 고가용성(High Availability) 입니다.

 

  • 부하 분산(Load Balancing)

부하 분산은 클러스터 앞 단에서 모든 클러스터 멤버로 부하를 균등하게 분산하는 것입니다. 이론적으로 클러스터를 사용하면 처리량은 클러스터를 구성하는 서버들의 성능을 합친 것이 됩니다. 처리량을 늘리고 싶다면 클러스터에 새로운 서버를 추가하여 전체 클러스터의 처리량을 늘릴 수 있습니다.

로드 밸런서의 역할

 

 

  • 고가용성(HA : High Availability)

고가용성은 클러스터 멤버에 장애가 발생할 경우 다른 멤버가 그 역할을 대신할 수 있도록 하는 것입니다. HA 클러스터링은 서비스의 다운 타임을 줄여줍니다. 클러스터의 한 서버가 중지될 경우에 다른 서버가 그 역할을 대신(Failover) 처리하여 고가용성을 제공합니다. 클러스터링을 구성하여 서비스를 중단 없이 항상 사용 가능한 상태를 유지할 수 있습니다.

웹 애플리케이션 서버의 HA 기능

 

 

  • JBoss EAP 6 클러스터

JBoss EAP 6에서는 웹 애플리케이션, EJB 애플리케이션, JMS 기능에 각각 클러스터링을 적용할 수 있습니다. JBoss EAP 6에는 설정을 편하게 할 수 있도록 프로파일 단위로 클러스터링이 가능한 구성 설정 파일을 제공하고 있습니다. 파일명의 뒷 부분에 ha, full-ha 프로파일이 클러스터링을 제공하는 프로파일입니다. 클러스터링을 구현하는 핵심 기술은 요청에 대한 로드 밸런싱과 상태를 복제하는 기술입니다.

 

 

 

  2. 클러스터링의 핵심 기술

(1) JGroups

JGroups는 멀티캐스트 프로토콜을 사용하여 신뢰성 높은 통신을 할 수 있도록 구현된 네트워크 통신 라이브러리입니다. JBoss EAP 6의 클러스터링 구현, Infinispan의 네트워크 캐시 구현, HornetQ의 클러스터링 구현 등에 JGroups(http://www.jgroups.org)가 사용됩니다.

 

JGroups에서 중요한 프로토콜은 가입과 탈퇴(JOIN/REMOVE), 장애 감지(FD, FD_SOCK), 파티션 결합(MERGE), PING 입니다.

항목 설명
가입(JOIN) JGroups를 시작할 때 만들어지는 멀티캐스트 그룹 가입을 위한 방식입니다.
처음으로 가입하여 다른 멤버가 없으면 리더(코디네이터)가 됩니다.
멤버가 있으면 기존리더에게 참가 요청을 하여 멤버 리스트에 추가해 달라고 합니다. 그러면 리더가 그룹에 속한 모든 멤버들에게 클러스터 멤버 리스트를 배포하고 정보를 공유합니다.
탈퇴(REMOVE) 탈퇴(REMOVE)는 JGroups 정지 시 멀티캐스트 그룹에서 탈퇴하기 위한 것입니다.
리더가 아닌 일반 멤버가 탈퇴하는 경우에는 리더가 클러스터 멤버 리스트를 업데이트하고, 다른 멤버에게 배포합니다.
리더 자신이 탈퇴하는 경우엔 두 번째 멤버가 리더가 되고 클러스터 멤버 리스트를 업데이트하여 다른 멤버에게 배포합니다.
마지막 멤버가 탈퇴하면 그 그룹은 없어집니다.
장애 감지(FD) 장애 감지(FD : Failure Detection)는 Heart Beat 메시지를 사용하여 오류가 발생한 멤버를 감지하는 것입니다.
각 멤버는 Heart Beat 메시지를 수신하여 응답 메시지를 보내 정상적인 상태임을 알려야 합니다.
지정한 타임아웃 시간 동안 재시도하여 응답을 받지 못하면,멤머에 오류가 발새한 것으로 간주하여 클러스터 멤버에서 제거합니다.
장애 감지 소켓
(FD_sOCK)
장애 감지 소켓(FD_SOCK)은 클러스터 멤버들 간에 TCP 소켓으로 A -> B -> C -> A 처럼 링 모양으로 연결하여 상태를 모니터링하기 위한 프로토콜입니다.
링 모양이기 때문에 각 멤버는 그 아웃 멤버만 감시하게 됩니다.
멤버 B가 정상 종료할 대는 멤버 A에 메시지를 보내 종료되는 것을 알려줍니다. 만약, 멤버 B에 장애가 발생하여 갑자기 종료되면, 멤버 A는 연결된 소켓이 비정상 죵료되는 것을 감지할 수 있습니다.
장애를 감지하면 확인 단계를 거치고 장애가 확실하면 클러스터 멤버 리스트에서 삭제합니다.
파티션 결합
MERGE2)
MERGE는 통신 장애 등 여러 가지 이유로 멀티캐스트 그룹이 여러 개로 나뉜 경우 쪼개진 그룹을 하나로 결합하기 위한 것입니다.
리더(코디네이터)는 주기적으로 리더가 여기 있다는 멀티캐스트 메시지를 보냅니다. 만약 그룹이 쪼개져서 만들어진 다른 그룹의 리더가 이 메시지를 받으면 결합 프로세스를 시작합니다. {A, B}와  {C, D, E}를 결합하여 하나의 {A, B, C, D, E}의 그룹으로 만듭니다
PING 처음 클러스터의 멤버를 발견하는데 사용하는 프로토콜입니다.
멀티캐스트 주소에 MPING 요청을 보내서 리더(코디네이터)를 찾고 다른 멤버들을 찾습니다. 멀티캐스트를 사용할 수 없는 환경에서는 TCPPING이나 GOSSIP 서버를 이용한 TCPGOSSIP, 공유 파일 시스템을 이요한 FILE_PING, 데이터베이스 테이블을 사용하는 JDBC_PING, 아마존 AWS 환경에서 S3(Simple Storage Service)를 사용한 S3_PING, 오픈 스택의 Swift를 사용한 SWIFT_PiNG 등 다양한 방식의 PING을 설정할 수 있습니다.

 

JBoss EAP 6에서는 ha, full-ha 프로파일에 jgroups 서브시스템이 설정되어 있습니다. jgroups 서브시스템에는 멀티캐스트를 사용하는 udp 프로토콜과 TCP를 사용하는 tcp 프로토콜 스택이 정의되어 있고, 기본적으로 udp 프로토콜을 사용하도록 설정되어 있습니다. 아래의 내용을 살펴보면 방금 설명한 FD, FD_SOCK, PING 등 여러가지 복잡한 값들이 설정되어 있습니다. 대부분 기본값을 그대로 사용하면 됩니다.

<subsystem xmlns="urn:jboss:domain:jgroups:1.1" default-stack="udp">
	<stack name"udp">
    	<transport type="UDP" socket-binding="jgroups-udp"/>
        <protocol type="PING"/>
        <protocol type="MERGE3"/>
        <protocol type="FD_SOCK" socket-binding="jgroups-udp-fd"/>
        <<protocol type="FD"/>
        <protocol type="VERIFY_SUSPECT"/>
        <protocol type="pbcast.NAKACK"/>
        <protocol type="UNiCAST2"/>
        <protocol type="pbcast.STABLE"/>
        <protocol type="pbcast.GMS"/>
        <protocol type="UFC"/>
        <protocol type="MFC"/>
        <protocol type="FRAG2"/>
        <protocol type="RSVP"/>
     </stack>
     <stack name="tcp">
     	<transport type="TCP" socket-binding="jgroups-tcp"/>
        <protocol type="MPING" socket-binding="jgroups-mping"/>
        <protocol type="MERGE2"/>
        <protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/>
        <protocol type="FD"/>
        <protocol type="VERIFY_SUSPECT"/>
        <protocol type="pbcast.NAKACK"/>
        <protocol type="UNiCAST2"/>
        <protocol type="pbcast.STABLE"/>
        <protocol type="pbcast.GMS"/>
        <protocol type="UFC"/>
        <protocol type="MFC"/>
        <protocol type="FRAG2"/>
        <protocol type="RSVP"/>
     </stack>
 </subsystem>

 

다음과 같이 default-stack을 tcp로 변경하면 TCP를 사용하도록 변경할 수 있습니다.

<subsystem xmlns="urn:jboss:domain:jgroups:1.1" default-stack="tcp">

 

 

(2) 멀티캐스트 통신

멀티캐스트 통신특정 주소에 참여하는 모든 호스트에 동시에 같은 메시지를 전송하는 통신 방식입니다. 멀티캐스트에 사용하는 주소는 IP 주소상의 D클래스로 앞의 4비트가 1110인 224.0.0.0 ~ 239.255.255.255 범위의 주소를 사용합니다. 라우터에서 사용하도록 예약된 주소가 있어 실제로 애플리케이션에서 사용할 수 있는 주소는 244.0.1.0 ~ 238.255.255.255 입니다.

 

멀티캐스트 통신의 장점은 패킷이 멀티캐스트 그룹 단위로 하나만 전송되기 때문에 네트워크 트래픽이 혼잡해지지 않는다는 것입니다. 유니캐스트는 멤버 수만큼 여러 번 패킷을 전송해야 합니다.

 

호스트에 여러 개의 네트워크 인터페이스 카드가 있으면 첫 번째 인터페이스를 멀티캐스트 통신에 사용합니다. 다음과 같이 설정하면 지정된 인터페이스 카드를 통해 멀티캐스트를 통신할 수 있습니다.

$ route add-net 231.12.21.0 netmask 255.255.255.0 <인터페이스>

 

IPv6를 사용할 수 있는 운영체제에서는 기존적으로 소켓이 IPv6를 사용하기 때문에 Java가 IPv6를 사용합니다. IPv4를 사용하도록 설정하려면 Java 실행 시 다음 옵션을 지정합니다.

-Djava.net.preferIPv4Stack=true

 

 

(3) 멀티캐스트 테스트

멀티캐스트는 먼저 운영체제에서 멀티캐스트할 수 있게 설정되어야 하며, 사용하는 라우터에서도 멀티캐스트 프로토콜을 지원해야 합니다. 멀티캐스트가 가능한 환경인지 테스트하는 방법이 필요합니다.

 

jgroups 라이브러리에는 마치 채팅과 같이 멀티캐스트를 사용하여 메시지를 보내는 테스트 애플리케이션을 제공하고 있습니다.

 

다음 명령으로 지정한 멀티캐스트 IP, 포트에 참여하여 메시지를 수신하는 애플리케이션을 시작합니다.

$ java -cp jgroups-3.2.5.Final.jar org.jgroups.tests.McastReceiverTest -mcast_addr 224.10.10.10 -port 5555

 

다음 명령으로 지정한 멀티캐스트 IP, 포트로 메시지를 보내는 애플리케이션을 실행하여, 멀티캐스트로 전송할 텍스트 메시지를 입력합니다.

$ java -cp jgroups-3.2.5.Final.jar org.jgroups.tests.McastSenderTest -mcast_addr 224.10.10.10 -port 5555
Socket #2=0.0.0.0/0.0.0.0:5555, ttl=32, bind interface=/192.168.023
Socket #4=0.0.0.0/0.0.0.0:5555, ttl=32, bind interface=/127.0.0.1
> test

 

먼저 실행한 멀티캐스트 수신 애플리케이션에 메시지가 수신되면, 멀티캐스트 통신이 정상적으로 동작하는 것입니다.

$ java -cp jgroups-3.2.5.Final.jar org.jgroups.tests.McastReceiverTest -mcast_addr 224.10.10.10 -port 55555
Socket=0.0.0.0/0.0.0.0:5555, bind interface=/192.168.0.28
Socket=0.0.0.0/0.0.0.0:5555, bind interface=/127.0.0.1
test [sender=192.168.0.23:55555]
test [sender=192.168.0.23:55555]

 

 

  3. 웹 애플리케이션 클러스터링

웹 애플리케이션의 클러스터링은 로드밸런싱과 세션 복제 두 가지 기능이 있습니다. 일반적인 구성은 다음 그림과 같습니다.

웹 애플리케이션의 클러스터링 구성

 

 

 

(1) 로드 밸런싱

웹 애플리케이션에서 로드 밸런싱웹 서버에서 요청을 여러 대의 웹 애플리케이션 서버로 분배하는 기능입니다. 이러한 방법으로 여러 서버로 부하를 분산하여, 특정 서버에만 부하가 많아지지 않도록 합니다. 또, 설정을 통해 특정 서버 노드에만 부하를 더 주는 것도 가능합니다. JBoss EAP 6에서는 웹 서버에서 사용할 수 있는 두 가지 로드 밸런싱 방법이 제공됩니다.

 

  • mod_jk 커넥터

mod_jk는 웹 서버에 설치하는 로드 밸런싱 모듈입니다. 애플리케이션 서버와 통신에 AJP 프로토콜을 사용합니다.

 

  • mod_cluster 커넥터

mod_cluster는 jboss.org에서 개발되고 있는 Apache 웹 서버와 함께 구성하는 로드 밸런싱 방법입니다. 옵션을 웹 서버가 아닌 JBoss에서 설정할 수 있습니다.

 

 

(2) 세션 복제

로드 밸런서는 효율적인 세션의 관리를 위해 스티키(Sticky) 세션을 사용합니다. 최초로 접속한 서버에 세션을 저장하고, 계속 해당 서버로만 요청합니다. 장애가 발생하여 접속한 애플리케이션 서버가 정지해 버리면, 로드 밸런서는 다른 서버로 요청을 다시 전송합니다. 이때, 요청을 받은 서버에 장애가 발생한 서버에서 생성된 세션 정보가 없으면 더는 처리할 수 없습니다. 일반적으로 세션에는 로그인 정보가 포함되어 있는데, 페일오버 되었을 경우 세션 정보가 없으면 로그아웃된 것으로 인식합니다. 이러한 경우를 대비하여 세션 정보를 미리 다른 서버에 전송하고 동기화 합니다. 이런 기능이 세션 복제 입니다.

 

 

① 세션 복제 시 주의점

  • 클러스터의 SPOF(Single Point Of Failure)를 방지하려면 세션을 하나 이상의 다른 서버에 복제해야 합니다.
  • HTTP 세션에 저장되는 값은 직렬화(Serializable)된 값이어야 합니다.
  • 멀티캐스트 주소가 같으면 같은 클러스터로 묶이게 됩니다. 서로 다른 서비스는 서로 다른 멀티캐스트 주소를 사용해야 합니다.
  • 성능을 위해서는 내부 클러스터링용으로 별도의 NIC를 사용하는 것이 좋습니다.

 

② 세션 복제 설정 방법

웹 애플리케이션에서 세션 클러스터링을 구성할 때 목적에 따라 적합한 로드 밸런스 모듈과 세션 복제 방법을 결정해야 합니다.

구분 설명
mod_jk를 이용한
로드 밸런싱
로드 밸런싱은 기본적으로 웹 서버에서 제공되는 기술입니다.
mod_jk 로드 밸런싱을 사용하려면 JBoss EAP 6에서는 AJP 커넥터 설정만 하면 됩니다.
ha, full-ha 프로파일에 AJP 커넥터가 설정되어 있습니다.
mod_jk는 요청 수나 세션 수를 기반으로 로드 밸런스할 수 있고, Cookie를 이요한 부하분산 설정도 가능합니다. 또, 세션유지 관리를 위한 스티키(Sticky) 세션 기능도 제공합니다.
mod_cluster를 이용한
로드 밸런싱
mod_cluster 로드 밸런싱을 사용하려면, 웹 서버의 설정뿐만 아니라 JBoss EAP 6의 mod_cluster도 설정해야 합니다.
ha, full-ha 프로파일에 modcluster 서브시스템이 설정되어 있습니다.
mod_cluster는 CPU 부하나 메모리 상황 등에 따라 동적으로 로드 밸런싱할 수 있습니다.
JBoss 인스턴스 자동 등록, 동적으로 부하를 계산하여 로드 밸런싱하는 등 클라우드 환경을 지원하기 위한 많은 기능을 제공합니다.
mod_cluster와 애플리케이션 서버 간 통신에는 AJP 프로토콜뿐만 아니라 HTTP, HTTPS 프로토콜도 사용할 수 있고, 스티키(Sticky) 세션도 지원합니다.

 

ha, full-ha 프로파일에는 세션이 복제되도록 설정되어 있기 때문에, 이 프로파일을 사용하는 JBoss EAP 6 인스턴스를 여러 개 기동하면, 자동으로 클러스터를 구성하여 세션을 복제합니다.

22:55:56,248 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 56) JBAS010281: Started default-host/session cache from web container
22:55:56,255 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 55) JBAS010281: Started repl cache from web container
22:55:56,264 INFO [org.jboss.as.clustering] (MSC service thread 1-2) JBAS010238: Number of cluster members: 2

 

실제 세션이 복제되려면, 웹 애플리케이션에 세션을 복제하겠다는 설정이 필요합니다. 웹 애플리케이션의 설정이 없으면 ha 프로파일을 사용하여 클러스터링이 구성되어 있어도, 세션은 복제되지 않습니다. 웹 애플리케이션에 세션을 복제하겠다는 설정은 web.xml 파일에 <distributable/> 태크를 추가하면 됩니다.

 

다음은 web.xml 파일에 <distributable/>을 추가하는 예제입니다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
	<display-name>session</display-name>
    
    <distributable/>
    
    <welcome-file-list>
    	<welcome-file>index.jsp</webcom-file>
    </welcome-file-list>
</web-app>

 

이외에는 일반 웹 애플리케이션을 작성하는 방법과 같습니다.

 

 

③ 세션 복제 상세설정

WEB-INF/jboss-web.xml 파일에서 세션 복제에 대한 상세한 설정을 지정할 수 있습니다. 다음은 세션 설정의 예제입니다.

<jboss-web>
	<context-root>/</context-root>
    <replication-config>
    	<cache-name>custom-session-cache</cache-name>
        <replication-trigger>SET</replication-trigger>
        <replication-granularity>ATTRIBUTE</replication-granularity>
        <use-jk>false</use-jk>
        <max-unreplicated-interval>30</max-unreplicated-interval>
        <snapshot-mode>INSTANT</snapshot-mode>
        <snapshot-interval>1000</snapshot-interval>
        <session-notification-policy>com.example.CustomSessionNotificationPolicy</session-notification-policy>
    </replication-config>
</jboss-web>

 

세션이 언제 복제될 것인지를 <replication-trigger>를 사용하여 설정할 수 있습니다. 사용할 수 있는 옵션은 다음과 같습니다.

  • SET : 세션이 설정될  때 복제
  • SET_AND_GET : 세션을 읽기만 해도 복제
  • SET_AND_nON_PRIMITIVE_GET : 세션이 설정될 때와 Java의 Primitive 타입이 아닌 타입은 읽을 때도 복제. 기본 설정값

또, <replication-granularity>를 사용하여 세션 복제 범위를 지정할 수 있습니다. 기본값은 SESSION으로 세션에 보관된 객체 전체를 복제합니다. 애트리뷰트(attribute)를 사용하면 세션 객체 중 변경된 애트리뷰트(attribute)만 복제하기 때문에 세션 복제 속도를 크게 향상할 수 있습니다.

 

 

④ 세션 타임아웃 설정

HTTP 프로토콜은 연결되지 않은 상태로 통신하기 때문에 부라우저의 쿠키와 서버의 세션을 사용하여 서로의 상태를 유지합니다. 연결되지 않은 상태이기 때문에 사용자가 웹 애플리케이션을 계속 사용하고 있는지 판단할 수 없습니다. 그래서 지정된 시간동안 세션을 사용하지 않으면, 그 세션을 삭제하는 세션 타임아웃 기능을 사용합니다. 웹 애플리케이션의 세션 타임아웃은 web.xml 파일의 <session-config>에서 설정합니다. jboss-web.xml 파일에서도 세션 타임아웃값을 다음과 같이 설정할 수 있습니다.

<jboss-web>
	<session-config
    	<session-timeout>120</session-timeout>
    </session-config>
</jboss-web>

 

 

(3) 세션 Passivation

세션에 너무 많은 데이터가 들어 있으면 어떻게 될까요? 세션은 기본적으로 메모리, 즉 Java의 Heap 메모리를 사용하기 때문에 OutOfMemory 오류가 발생할 수 있습니다. 그래서 기본적으로 세션에는 최소한의 값만 저장하는 것입니다. 하지만 이미 개발된 애플리케이션을 수정하기 어렵다면 이런 방법을 사용할 수 있습니다.

 

패시베이션(Passivation)자주 사용되지 않는 세션을 메모리에서 삭제하고, 디스크에 저장하여 메모리를 효율적으로 사용하는 방법입니다. 반대로 액티베이션(Activation)디스크에 저장된 데이터를 메모리에 읽어 들이는 것을 말합니다.

 

HTTP 세션의 패시베이션은 다음 3가지 상황에서 발생합니다.

  • 새로운 세션을 만들려고 할 때, 이미 최대 액티브 세션 수를 넘었기 때문에 서버는 세션 일부를 디스크에 저장하고 새 세션을 만듧니다.
  • 주기적으로 백그라운드 작업을 통해 세션을 디스크에 저장합니다.
  • 웹 애플리케이션이 배포되어 있고 새로 배포되는 웹 애플리케이션의 세션 관리자가 다른 서버의 세션 백업 본을 가져오는 경우에 세션이 패시베이션될 수 있습니다.

 

 

① 세션 패시베이션 설정

세션 패시베이션은 애플리케이션 WEB_INF/jboss-web.xml 파일에 설정합니다.

<jboss-web>
	<max-active-sessions>20</max-active-sessions>
    <passivation-config>
    	<use-session-passivation>true</use-session-pasivation>
        <passivation-min-idle-time>60</passivation-min-idle-time>
        <passivation-max-idle-time>60</passivation-max-idle-time>
    </passivation-config>
</jboss-web>

 

세션 패시베이션 설정 항목들은 다음과 같습니다.

구분 설명 기본값
<max-active-sessions> 허용되는 세션의 최대 수
패시베이션을 사용할 때 세션 수가 이 값을 초과하면 설정된 <passivation-min-idle-time>을 초과한 세션들이 저장됩니다.
그래도 허용 세션 수 제한을 초과하면 새로운 세션을 만들지 못합니다.
-1
(제한
없음)
<use-session-passivation) 세션 패시베이션을 사용할 것인지 설정 false
<passivation-min-idle-time> 최대 세션 수를 유지하기 위해 패시베이션될 때 이 시간만큼 사용되지 않은 세션이 대상이 됩니다. -1
<passivation-max-idle-time> 지정된 시간 이상 사용되지 않은 세션이 패시베이션됩니다.
최대 세션 수와 상관없이 지정된 시간이 되면 패시베이션 됩니다.
web.xml의 <session-timeout> 설정보다 작은 값으로 설정해야 합니다.
-1

 

 

 

(4) 쿠기 도메인

쿠기 도메인은 애플리케이션을 사용하는 클라이언트의 웹 브라우저에서 쿠키를 읽을 수 있는 호스트를 지정하는 방법입니다. 쿠키 도메인의 기본값은 '/'입니다. 기본적으로 쿠키를 만든 호스트에서만 쿠키의 내용을 읽을 수 있습니다. 다른 호스트에서도 쿠키의 내용을 읽을 수 있게 하려고 쿠키 도메인을 설정합니다.

 

예를 들어 SSO(Single Sign On)을 사용하여 로그인 정보를 공유하기 위해 SSO 밸브를 사용하여 쿠키 도메인을 설정하는 방법을 알아봅시다.

 

다음 설정은 다른 서버에서 실행되는 서로 다른 애플리케이션이 http://app1.test.com과 http://app2.test.com에서 SSO 컨텍스트를 공유할 수 있는 설정입니다. 

<Valve className="org.jboss.web.tomcat.service.sso.ClusteredSingleSignOn" cokieDomain="test.com"/>

 

 

 

(5) TCP 클러스터링 방법

jgroups 서브시스템의 default-stack을 'tcp'로 변경하면 멀티캐스트가 아닌 TCP를 사용하게 됩니다. 하지만 멀티캐스트가 전혀 동작하지 않는 아마존 웹 서비스(AWS)와 같은 환경에서는 이 설정만으로는 동작하지 않습니다.

 

그 이유는 tcp 스택으로 변경하더라도 tcp 스택에 클러스터 멤버를 찾기 위한 PING 프로토콜로 멀티캐스트를 사용하는 'MPING'을 사용하도록 설정되어 있기 때문입니다.

<protocol type="MPING" socket-binding="jgroups-mping"/>

 

멀티캐스트를 사용하지 않는 PING 프로토콜로 변경해야 합니다. 멀티캐스트를 사용하지 않는 경우에는 TCPPING, FILE_PING, S3_PING, TCPGOSSIP, JDBC_PING 등 다양한 PING 프로토콜들이 있습니다. 이 방법 중 다음에서 TCPPING 설정 방법을 살펴봅시다.

 

다음과 같이 TCPPING의 initial_hosts 프로퍼티로 호스트의 IP와 포트를 지정하면 됩니다. 시스템 프로퍼티로 값을 변경할 수 있도록 값을 설정합니다.

<subsystem xmlns="urn:jboss:domain:jgroups:1.1" default-stack="tcp">
... 생략 ...
<stack name="tcp">
	<transport type="TCP" socket-binding="jgroups-tcp"/>
    	<protocol type="TCPPING">
        	<property name="initial_hosts">${jgroups.tcpping.initial_hosts:192.168.0.11[7600], 192.168.0.11[7700], 192.168.0.12[7600], 192.168.0.12[7700]}</property>
            <property name="port_range">0</property>
            <property name="timeout">3000</property>
            <property name="num_initial_members">3</property>
        </protocol>
        <protocol type="MERGE2"/>
        <protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/>
        <protocol type="FD"/>
        <protocol type="VERIFY_SUSPECT"/>
        <protocol type="pbcast.NAKACK"/>
        <protocol type="UNICAST2"/>
        <protocol type="pbcast.STABLE"/>
        <protocol type="pbcast.GMS"/>
        <protocol type="UFC"/>
        <protocol type="MFC"/>
        <protocol type="FRAG2"/>
        <protocol type="RSVP"/>
</stack>

 

 

 

  4. 웹 서버 설치

JBoss EAP 6에 포함된 웹 서버인 Apache HTTPD는 레드햇 고객 서비스 포탈에서 다운로드할 수 있습니다.

웹 서버 설치 방법은 다음과 같습니다. 웹 서버는 80포트를 사용하기 때문에 root 계정으로 실행해야 합니다.

 

(1) JBoss EAP 6 Apache HTTP Server 다운로드

RED Hat 고객 서비스 포탈(http://access.redhat.com)에서 JBoss EAP 6 다운로드 목록으로 이동합니다.

 

목록에서 운영체제와 아키텍처에 해당하는 Apache HTTP Server 바이너리를 찾아 다운로드 합니다.

 

(2) 필요 패키지 설치

웹 서버에 필요한 패키지를 설치합니다.

$ sudo yum install nss elinks apr-devl apr-util-devel krb5-workstation mod_auth_kerb

 

(3) 다운로드 한 Apache HTTP Server 파일 압축 풀기

웹 서버를 설치할 디렉터리에 ZIP 파일의 압축을 풉니다.

$ cd /CLUOD/APACHE
$ unzip ~/Downloads/jboss-ews-httpd-2.0.1-RHEL6-x86_64.zip

 

(4) postinstall 실행

설치된 웹 서버의 httpd 디렉터리에서 .postinstall을 실행합니다.

$ cd jboss-ews-2.0/httpd
$ ./postinstall

 

(5) 웹 서버 실행

웹 서버를 실행합니다.

$ cd sbin
$ sudo ./apachectl start

 

(6) 웹 서버 실행 확인

해당 서버 IP로 접속하여 서비스가 정상인지를 확인합니다.

웹 브라우저 실행 후 URL에 localhost를 입력합니다.

 

(7) 웹 서버 정지

웹 서버 정지 방법은 아래와 같습니다.

$ ./apachectl stop

 

만약 웹 브라우저에서 웹 서버로 접속되지 않을 경우에는 아래와 같이 방화벽을 중지한 후 다시 접속을 시도합니다.

$ sudo service iptables stop
iptables: Flushing firewall rules:						[ OK ]
iptables: Setting chains to policy ACCEPT: filter		[ OK ]
iptables: Unloading modules:							[ OK ]

 

이후에도 방화벽 사용을 계속 중지하려면 다음과 같이 설정합니다.

$ sudo chkconfig iptables off

 

 

 

  5. 웹 커넥터 종류

웹 서버는 요청을 애플리케이션 서버 또는 웹 애플리케이션 서버 클러스터에 전달합니다. Apache HTTPD Server 기반 제품인 JBoss EWS(Enterprise Web Server)에서 사용할 수 있는 커넥터는 mod_jk, mod_proxy, mod_cluster 모듈들이 있습니다. 또, Microsoft IIS 서버에서 사용할 수 있는 커넥터와 Sun ONE Web Server에서 사용할 수 있는 커넥터가 있습니다.

 

가장 최근에 만들어진 mod_cluster는 클러스터의 노드들을 자동으로 찾아 로드 밸런싱하는 기능을 제공합니다. 또, 애플리케이션 배포를 감지하여 애플리케이션이 배포된 노드에만 요청을 전달할 수 있는 기능도 제공하고 있습니다.

 

<웹 서버 커넥터의 종류와 주요 특징>

커넥터 웹 서버 운영체제 프로토콜 애플리케이션
상태지원
스티키
세션
mod_cluster JBoss EWS
(Apache HTTPD)
RHEL 5/6
Windows 2008 Server
Solaris 10/11
AJP,
HTTP,
HTTPS
O O
mod_jk JBoss EWS
(Apache HTTPD)
RHEL 5/6
Windows 2008 Server
Solaris 10/11
AJP X O
mod_proxy JBoss EWS
(Apache HTTPD
RHEL 5/6
Windows 2008 Server
Solaris 10/11
HTTP,
HTTPS
X O
ISAPI Microsoft IIS Windows 2008 Server AJP X O
NSAPI Sun ONE Web Server Solaris 10/11 AJP X O

 

 

  6. mod_jk 커넥터

(1) mod_jk 개요

아파치 웹 서버는 전 세계적으로 가장 많이 사용되는 대표적인 웹 서버이며 플러그이니 모듈을 사용하여 확장할 수 있습니다.

 

mod_jk 커넥터는 아파치 웹 서버에 로드되는 mod_jk.so 모듈입니다. 이 모듈은 클라이언트 요청을 받아 JBoss EAP에 전송하고, JBoss EAP는 이 요청을 받아 웹 서버에 보냅니다.

 

(2) mod_jk 설정 방법

<점검 사항>

  • 앞에서 언급한 "JBoss EAP 6 APache HTTP 서버 설치"에 따라 웹 서버가 설치되어 있어야 합니다.
  • root 권한을 사용하여 설치해야 합니다.

 

<mod_jk 설정 절차>

① mod_jk.conf 파일 작성

Apache HTTP 서버가 설치된 디렉터리의 conf.d 디렉터리($HTTPD_HOME/conf.d)에서 mod_jk.conf 파일을 열어 아래의 내용들을 참조하여 환경에 맞게 작성합니다.

# Load mod_jk module
# Update this path to match your modules location
LoadModule jk_module	modules/mod_jk.so

# Where to find workers.properties
# Update this path to match your conf directory location (put workers.properties next to httpd.conf)
JkWorkersFile conf.d/workers.properties

# Where to put jk logs
# Update this path to match your logs directory location (put mod_jk.log next to access_log)
JkLogFile	logs/mod_jk.log
JkShmFile	logs/mod_jk.shm

# Set the jk log level [debug/error/info]
JkLogLevel	info

# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

# JkOptions indicate to send SSL KEY SIZE,
JkOptions	+ForwardKeySize +ForwardURICompat -ForwardDirectories +ForwardURICompatUnparsed

# JkRequestLogFormat set the request format
JkRequestLogFormat	"%w %v %T"

# Send everything for context /examples to worker named worker1 (ajp13)
JkMount	/*.jsp lb
JkMount	/*.do lb
JkMount	/*.mvc lb
JkMount	/jkstatus* jkstatus

# Add jkstatus for managing runtime data
<Location /jkstatus>
JkMount jkstatus
Order Deny,Allow
Allow from 127.0.0.1
Allow from 192
Deny from all
</Location>

 

② workers.properties 파일 작성

Apache HTTP 서버가 설치된 디렉터리의 conf.d 디렉터리($HTTPD_HOME/conf.d/)에서 workers.properties 파일을 열어 아래의 내용들을 참조하여 환경에 맞게 작성합니다.

 

여기서 주의할 것은 worker.properties에 balance_worker 리스트에 호스트명과 JBoss EAP의 instance0id와 같아야 합니다. 여기서 instance-id는 server1, server2로 지정합니다.

worker.list=lb,jkstatus

# Templates
worker.template.type=ajp13
worker.template.maintain=60
worker.template.lbfactor=1
worker.template.ping_mode=A
worker.template.ping_timeout=2000
worker.template.prepost_timeout=2000
worker.template.socket_timeout=60
worker.template.socket_connect_timeout=2000
worker.template.socket_keepalive=true
worker.template.connection_pool_timeout=60
worker.template.connect_timeout=10000
worker.template.recovery_options=7

# Set properties for server1 (ajp13)
worker.server1.reference=worker.template
worker.server1.host=127.0.0.1
worker.server1.port=8009

# Set properties for server2 (ajp13)
worker.server2.reference=worker.template
worker.server2.host=127.0.0.1
worker.server2.port=8009

worker.lb.type=lb
worker.lb.balance_workers=server1,server2
worker.lb.method=Session
worker.lb.sticky_session=True

worker.jkstatus.type=status

 

③ 웹 커넥터 라이브러리를 다운로드

레드햇 고객 포탈에 접속하여 OS 플랫폼에 맞는 JBoss EAP 6의 웹 커넥터 네이티브 패키지를 다운로드 합니다.

 

④ HTTPD 모듈 디렉터리에 mod_jk.so 파일 복사

다운로드한 웹 커넥터 네이티브 패키지 압축해제를 합니다.

$ cd /CLOUD/JBOSS
$ unzip ~/Downloads/jboss-eap-native-webserver-connectors-6.2.0-RHEL6-x86_64.zip
Archive:	/home/admin/Downloads/jboss-eap-native-webserver-connectors-6.2.0-RHEL6-x86_64.zip
	creating: jboss-eap6.2/modules/system/layers/base/native/
    creating: jboss-eap6.2/modules/system/layers/base/native/etc/
    ... 생략 ...
    creating: jboss-eap6.2/modules/system/layers/base/native/lib64/httpd/modules/
    inflating: jboss-eap-6.2/modules/system/layers/base/nativelib64/httpd/modules/mod_jk.so
    inflating: jboss-eap-6.2/modules/system/layers/base/nativelib64/httpd/modules/mod_manager.so
    inflating: jboss-eap-6.2/modules/system/layers/base/nativelib64/httpd/modules/mod_advertise.so
    inflating: jboss-eap-6.2/modules/system/layers/base/nativelib64/httpd/modules/mod_proxy_cluster.so
    inflating: jboss-eap-6.2/modules/system/layers/base/nativelib64/httpd/modules/mod_slotmem.so
    inflating: jboss-eap-6.2/SHA256SUM

 

mod_jk.so 파일을 $HTTPD_HOME/modules에 복사합니다.

$ /CLOUD/JBOSS/jboss-eap-6.2/modules/system/layers/base/native/lib64/httpd/modules/
$ cp mod_jk.so /CLOUD/APACHE/jboss-ews-2.0/httpd/modules/

 

 

⑤ 웹 서버 restart

mod_jk 환경 설정 후 웹 서버를 restart 합니다.

$ cd /CLOUD/APACHE/jboss-ews-2.0/httpd/sbin
$ sudo ./apachectl restart

 

 

⑥ jkstatus를 통해 정상 동작 확인

http://localhost/jkstatus에 접속하여 정상 작동을 확인합니다.

 

 

 

(3) mod_jk.conf 설정 항목

구분 설정 방법 예제
JkMount JkMount는 웹 서버가 mod_jk 모듈로 전송할 URL을 지정합니다.
지시어 설정에 따라 mod_jk는 받은 URL을 올바른 Servlet 컨테이너에 전송합니다.
정적 콘텐츠는 웹 서버에서 제공하고, Java 애플리케이션만 부하 분산을 사용하려면 URL 경로가 /application/* 이거나 확장자를 사용하여 /*.jsp와 같이 지정합니다.

JkMount /*.jsp lb
JkMountFile mod-jk.conf의 JkMount 외에도 mod_jk에 전달되는 여러 URL 패턴을 포함하는 별도의 파일을 지정할 수 있습니다. 여러 URL 패턴을 설정하기 위해서 $HTTPD_HOME/conf/uriworkermap.properties라는 파일을 생성합니다.

JkMountFile conf/uriworkermap.properties

 

 

(4) workers.properties 설정

workers.properties 파일은 클라이언트 요청을 전달하는 워커 노드의 동작을 정의합니다. 이 파일은 $HTTPD_HOME/conf/workers.properties에 있습니다. workers.properties 파일은 웹 서버와 연결되는 여러 개의 서블릿 컨테이너의 위치와 컨테이너 전체에 부하를 분산시키는 방법을 정의합니다.

 

설정은 크게 세 가지 부분으로 구성됩니다.

  • 모든 워커 노드에 적용되는 전역 프로퍼티
  • 각각의 워커에게 적용되는 설정
  • 로드 밸런싱을 위한 워커 리스트 설정

 

프로퍼티의 구조는 worker.WORKER_NAME입니다. WORKER_NAME이 워커의 고유 이름이고, JBoss EAP 6의 웹 서브시스템에서 설정한 instance-id와 같은 이름이어야 합니다.

 

<worker 설정 항목>

구분 항목 설명
전역 프로퍼티 worker.list mod_jk에서 사용하는 워커 리스트
이 워커들이 요청을 받을 수 있습니다.
워커 리스트 type 워커의 타입(기본 타임은 ajp13)
가능한 타임은 ajp14, lb, status입니다.
balance_workers 로드 밸런서가 관리할 워커를 지정
컴마로 구분한 워커 리스트를 작성합니다.
sticky_session 같은 세션에 대한 요청이 항상 같은 워커로 라우팅할 것인지를 지정
기본값은 0으로 스티키 세션을 사용하지 않습니다.
스티키 세션을 사용하려면 1이나 True로 설정합니다.
로그인이 필요한 애플리케이션이면 일반적으로 스티키 세션을 사용하도록 설정해야 합니다.
워커 host 워커의 호스트 이름 또는 IP 주소
기본값은 localhost 입니다.
port JBoss 서버 인스턴스의 AJP 포트 번호
기본값은 8009 입니다.
ping_mode JBoss 서버의 상태를 검사하는 방법을 지정
검사 방법은 CPing 이라는 빈 AJP13 패킷을 보내 응답 CPong을 받습니다.

ping_mode는 C, P, I, A를 조합하여 사용합니다.
C : Connect. 서버에 연결한 후 한 번만 연결을 검사합니다.
      connect_timeout 값을 사용하여 제한 시간을 지정합니다.
      지정하지 않으면 ping_timeout을 사용합니다.

P : Prepost. 서버에 요청을 보내기 전에 연결을 검사합니다.
      prepost_timeout을 사용하여 제한 시간을 지정합니다.
      지정하지 않으면 ping_timeout을 사용합니다.

I : Interval. connecttion_ping_interval에 지정된 간격으로 연결을 검사합니다.

A : All. 위의 모든 연결 검사 방법을 사용하도록 설정합니다.
ping_timeout,
connect_timeout,
prepost_timeout,
connection_ping_interval
연결 검사 설정의 제한 값
값은 밀리 초 단위입니다.
ping_timeout의 기본값은 10000입니다.
lbfactor 각 워커의 부하 분산 지수를 지정합니다.
이것은 더 사양이 좋은 서버에 더 많은 부하를 할당하는 경우에 사용합니다.
에를 들어 특정 워커에 다른 워커의 3배 부하를 할당하려면 3으로 설정합니다.

worker.myworker.lbfactor=3

 

 

(5) JBoss EAP 6에 AJP 설정

JBoss EAP 6와 JBoss EAP 6 Apache HTTP Server를 mod_jk로 연결하기 위해서는 웹 서버와 mod_jk 커넥터가 설치되어 있어야 합니다. 설치되어 있지 않으면 먼저 설치합니다.

 

  • '4. 웹 서버 설치'에 따라 웹 서버가 설치되어 있어야 합니다.
  • '6. mod_jk 커넥터 설정방법'에 따라 커넥터가 설정되어 있어야 합니다.

 

<작업수행>

아래와 같이 웹 서버와 JBoss EAP 6 인스턴스 2개를 Port Off Set을 100으로 하여 같은 머신에서 구성합니다. 웹 서버의 구성 부분은 앞서 설명한 JBoss EAP 6 Apache HTTP Server 구성과 mod_jk 구성과 같은 내용이므로 필요한 경우 앞의 내용을 참조하여 진행합니다.

웹 서버와 JBoss 인스턴스의 연결 구성

 

 

그림에서는 3개의 서버에 웹 서버와 JBoss EAP 6를 설치하는 구성으로 설명하였지만 따라 하기에서는 웹 서버와 JBoss EAP 6 인스턴스인스턴스를 모두 한 머신에서 설정하는 것으로 설명하고 있습니다.

 

① mod_jk.conf 파일 작성

Aapche HTTPD 서버가 설치된 디렉터리의 conf.d 하위 디렉터리($HTTPD_HOME/conf.d)에 mod_jk.conf 파일을 아래의 내용들을 참조하여 환경에 맞게 작성합니다.

# Load mod_jk module
# Update this path to match your modules location
LoadModule jk_module	modules/mod_jk.so

# Where to find workers.properties
# Update this path to match your conf directory location (put workers.properties next to httpd.conf)
JkWorkersFile conf.d/workers.properties

# Where to put jk logs
# Update this path to match your logs directory location (put mod_jk.log next to access_log)
JkLogFile	logs/mod_jk.log
JkShmFile	logs/mod_jk.shm

# Set the jk log level [debug/error/info]
JkLogLevel	info

# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

# JkOptions indicate to send SSL KEY SIZE,
JkOptions	+ForwardKeySize +ForwardURICompat -ForwardDirectories +ForwardURICompatUnparsed

# JkRequestLogFormat set the request format
JkRequestLogFormat	"%w %v %T"

# Send everything for context /examples to worker named worker1 (ajp13)
JkMount	/*.jsp lb
JkMount	/*.do lb
JkMount	/*.mvc lb
JkMount	/jkstatus* jkstatus

# Add jkstatus for managing runtime data
<Location /jkstatus>
JkMount jkstatus
Order Deny,Allow
Allow from 127.0.0.1
Allow from 192
Deny from all
</Location>

 

 

② workers.properties 파일 작성

Apache HTTP 서버가 설치된 디렉터리의 conf.d 하위 디렉터리($HTTPD_HOME/conf.d/)에 workers.properties 파일을 아래의 내용을 참조하여 환경에 맞게 작성합니다.

 

여기서 주의할 것은 worker.properties에 balance_worker 리스트에 호스트명과 JBoss EAP의 instance-id명이 같아야 합니다. 여기서 instance-id 명은 server1, server2로 지정합니다.

worker.list=lb,jkstatus

# Templates
worker.template.type=ajp13
worker.template.maintain=60
worker.template.lbfactor=1
worker.template.ping_mode=A
worker.template.ping_timeout=2000
worker.template.prepost_timeout=2000
worker.template.socket_timeout=60
worker.template.socket_connect_timeout=2000
worker.template.socket_keepalive=true
worker.template.connection_pool_timeout=60
worker.template.connect_timeout=10000
worker.template.recovery_options=7

# Set properties for server1 (ajp13)
worker.server1.reference=worker.template
worker.server1.host=127.0.0.1
worker.server1.port=8009

# Set properties for server2 (ajp13)
worker.server2.reference=worker.template
worker.server2.host=127.0.0.1
worker.server2.port=8109

worker.lb.type=lb
worker.lb.balance_workers=server1,server2
worker.lb.method=Session
worker.lb.sticky_session=True

worker.jkstatus.type=status

 

 

③ HTTPD 모듈 디렉터리에 mod_jk.so 파일 복사

mod_jk.so 파일을 $HTTPD_HOME/modules에 복사합니다.

$ /CLOUD/JBOSS/jboss-eap-6.2/modules/system/layers/base/native/lib64/httpd/modules/
$ cp mod_jk.so /CLOUD/APACHE/jboss-ews-2.0/httpd/modules/

 

복사한 후 Apache HTTPD Server를 재기동합니다.

 

$ cd /CLOUD/APACHE/jboss-ews-2.0/httpd/sbin
$ sudo ./apachectl restart

 

④ standalone-ha.xml 파일 수정

standalone-ha.xml 파일의 웹 서브시스템에 instance-id 속성을 추가합니다.

$ vim $JBOSS_HOME/standalone/configuration/stadalone-ha.xml

 

웹 서브시스템을 찾아 환경 변수 jboss-node-name을 사용할 수 있도록 instance-id 속성을 추가합니다.

<subsystem xmlns="urn:jboss:domain:web:1.5" default-virtual-server="default-host" instance-id="${jboss.node.name}" native="false">

 

⑤ JBoss server1 실행 스크립트 작성

$JBOSS_HOME/server1 디렉터리에서 server.sh 실행 스크립트를 작성합니다.

$ cd $JBOSS_HOME
$ cp -R standalone server1
$ cd server1
$ vim server1.sh

 

server1.sh 파일의 내용을 다음과 같이 작성합니다.

#!/bin/sh
$JBOSS_HOME/bin/standalone.sh -c standalone-ha.xml -b 127.0.0.1 -bmanagement 127.0.0.1 -Djboss.socket.binding.port-offset=0 -Djboss.node.name=server1 -Djboss.server.base.dir=$JBOSS_HOME/server1

 

server1.sh 파일에 실행 권한을 부여합니다.

$ chmod u+x server1.sh

 

server1.sh 파일을 실행하여 JBoss EAP 6 server1 인스턴스를 실행합니다.

$ ./server1.sh

 

 

⑥ server1에 session.war 파일 배포

  • http://localhost:9990/console/에 접속하여 server1 인스턴스에 session.war 파일을 배포합니다.
  • session.war 파일은 세션에 Integer 값을 하나 저장하고 요청 때마다 세션에 저장된 값을 하나씩 증가시키는 간단한 JSP 프로그램입니다.
  • http://github.com/nameislocus/session에서 다운로드 할 수 있습니다. 
  • Runtime → Manage Deployments → Add르르 클릭하여 session.war 파일을 선택하고 'Save' 합니다.
  • 'En/Disable' 버튼을 클릭하여 session.war 애플리케이션을 Enable 합니다.

 

⑦ Jboss server2 실행 스크립트 작성

$JBOSS_HOME/server2 디렉터리에서 server.sh 실행 스크립트를 작성합니다.

$ cd $JBOSS_HOME
$ cp -R standalone server2
$ cd server2
$ vim server2.sh

 

server2.sh 파일의 내용을 다음과 같이 작성합니다.

#!/bin/sh
$JBOSS_HOME/bin/standalone.sh -c standalone-ha.xml -b 127.0.0.1 -bmanagement 127.0.0.1 -Djboss.socket.binding.port-offset=100 -Djboss.node.name=server2 -Djboss.server.base.dir=$JBOSS_HOME/server2

 

server2.sh 파일에 실행 권한을 부여합니다.

$ chmod u+x server2.sh

 

server2.sh 파일을 실행하여 JBoss EAP 6 server2 인스턴스를 실행합니다.

$ ./server2.sh

 

⑧ server2에 session.war 파일 배포

http://localhost:10090/console/에 접속하여 server2 인스턴스에도 session.war 파일을 배포합니다. 위에서 설명한 ㅇ6과 같은 방법으로 server에도 배포합니다.

 

 

<mod_jk 구성 테스트>

mod_jk로 연결된 웹 서버와 JBoss EAP 6 인스턴스 간의 로드 밸런싱과 세션복제 상태를 검증합니다. 먼저 mod_jk의 구성이 잘 되어 정상적으로 기동되었는지 확인해야 합니다.

 

웹 브라우저에서 http://localhost/jkstatus로 접속하면 mod_jk와 JBoss 인스턴스 간의 연결 상태가 표시됩니다.

이제 세션 복제가 되고 있는지 웹 브라우저를 사용하여 테스트해 봅시다.

 

웹 브라우저에서 요청을 보내면 웹 서버는 mod_jk를 통해 연결된 JBoss 인스턴스로 요청을 전달합니다. 접속된 JBoss 인스턴스를 정지시켰을 때 정상적으로 다른 jBoss 인스턴스에 요청이 전달되고 세션 정보가 업데이트 되는지를 확인합니다.

 

① 1번째 요청 전송

웹 브라우저를 열고 http://localhost/session/index.jsp URL을 입력하여 웹 서버로 1번째 요청을 보내면 세션ID를 표시하는 페이지가 출력됩니다. 세션ID의 뒤에 '.server1'이 접속한 JBoss 인스턴스의 instance-id 입니다.

 

② 접속한 1번 JBoss 인스턴스 정지

Ctrl + C를 눌러 세션이 생성된 JBoss 인스턴스 server1을 중지합니다.

17:20:27,265 INFO	[org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http;//127.0.0.1:9990
17:20:27,266 INFO	[org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) started in 19045ms - Started 175 of 299 services (123 services are passive or on-demand)
17:20:28,919 INFO	[org.jboss.as.clustering] (Incoming-1,shared=udp) JBAS010225: New cluster view for partition web (id; 1, delta: 1, merge: false) : [server1/web, server2/web]
17:20:28,920 INFO	[org.infinispan.remoting.transport.jgroups.JGroupsTransport] (Incoming-1,shared=udp) ISPN000094: Received new cluster view: [server1/web|1] [server1/web, server2web]
17:21:00,889 INFO	[stdout] (ajp-/127.0.0.1:8009-1)
session=ABrqVi3VCi74Lu1Smwe+p8U.server1
^C
... 생략 ...
17:21:16,211 INFO	[org.infinispan.remoting.transport.jgroups.JGroupsTransport] (MSC service thread 1-2) ISPN000082: Stopping the RpcDispatcher
17:21:16,228 INFO	[org.jboss.as] (MSC service thread 1-1) JBAS015950: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) stopped in 564ms

 

③ 2번째 요청 전송

웹 브라우저에서 '새로 고침'을 클릭하여 웹 서버로 2번째 요청을 보내면 세션 ID가 '.server2'로 변경됩니다.

세션에 저장된 숫자 값이 '2'로 변경된 것을 확인할 수 있습니다.

 

 

④ 정지 상태인 1번 JBoss 인스턴스를 다시 실행

앞서 정지시켰던 server1 JBoss 인스턴스를 실행합니다. 이 단계는 server2 JBoss 인스턴스를 정지시키기전에 상태 정보를 백업하기 위한 것입니다.

$ ./server1.sh
... 생략 ...
17:23:23,141 INFO	[org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://127.0.0.1:9990/management
17:23:23,142 INFO	[org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990
17:23:23,1443 INFO	[org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) started in 10619ms - Started 175 of 299 services (123 services are passive or on-demane)

 

⑤ 2번 JBoss 인스턴스 정지

현재 세션이 생성되어 있는 server JBoss 인스턴스를 정지합니다.

17:22:48,812 INFO	[stdout] (ajp-/127.0.0.1:8109-3) session=ABrqVi3VCi74JLu1Smwe+p8U.server2
17:23:22,031 INFO	[org.jboss.AS.clustering] (Incoming-9,shared=udp) JBAS010225: new Cluster view for partition web (id: 3, delta: 1, merge: false) : [server2/web, server1/web]
... 생략 ...
17:25:09,232 INFO	[org.infinispan.remoting.transport.jgroups.JGroupsTransport[ (MSC service thread 1-2) ISPN000082: Stopping the RpcDispatcher
17:25:09,250 INFO	[org.jboss.as] (MSC service thread 1-1) JBAS015950: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) stopped in 545ms

 

⑥ 3번째 요청 전송

웹 브라우저에서 3번째 요청을 보내면 세션에 저장된 값이 3으로 변경되고 'server1'로 요청이 전달됩니다.

 

 

웹 브라우저에서 총 3번의 요청을 전송하였고 접속한 JBoss 인스턴스를 강제로 종료하였음에도 불구하고 세션에 저장된 카운트는 차례로 증가하여 3이 되었고, 세션 아이디는 같음을 확인할 수 있었습니다. 즉, JBoss 인스턴스의 장애 상황에서도 세션 정보가 정상적으로 유지되는 것을 확인할 수 있었습니다.

 

 

 

  7. mod_cluster 커넥터

(1) mod_cluster 개요

JBoss HTTP 커넥터인 mod_cluster는 JBoss EAP의 지능형 부하 분산 솔루션입니다. JBoss mod_cluster 커뮤니티 프로젝트에서 개발하고 있습니다. 전통적인 HTTP 기반 로드 밸런서들의 단점을 보완하기 위해서 시작한 프로젝트입니다.

 

mod_cluster는 mod_jk와 마찬가지로 웹 서버에서 클라이언트 요청을 JBoss 인스턴스로 포워딩하는 기능을 제공하는 HTTP 기반 로드 밸런싱 모듈입니다. mod_clusterMod-Cluster Management Protocol(MCMP)이라는 추가적인 채널을 제공하여 전통적인 로드 밸런서 모듈보다 좀 더 정교하고, 안정적인 서비스를 제공하는 지능적인 HTTP 기반 로드 밸런서 입니다.

 

<mod_cluster의 주요 특징>

  • Mod_Cluster Management Protocol(MCMP)는 JBoss 인스턴스와 웹 서버 사이의 연결 프로토콜입니다. JBoss 인스턴스의 부하분산 요소와 생명 주기 이벤트를 웹 서버로 전송합니다.
  • JBoss 인스턴스를 추가할 때 웹 서버의 설정을 변경하지 않아도 됩니다.
  • 애플리케이션 서버는 부하 분산 요소(factor)의 계산이 다른 커넥터보다 정확합니다.
  • mod_cluster 통해 애플리케이션 생명 주기를 제어할 수 있습니다. 웹 서버는 JBoss 인스턴스에 배포된 웹 애플리케이션 컨텍스트 정보를 알 수 있습니다. 즉, 애플리케이션이 배포된 JBoss 인스턴스에만 요청을 포워딩할 수 있기 때문에, 서버 중지나 애플리케이션 배포 시 사용자에게 404 오류가 출력되지 않습니다.
  • HTTP, HTTPS, AJP 등 다양한 프로토콜로 포워딩할 수 있습니다.

 

 

(2) mod_cluster 구성 및 설치

① 웹 서버 커넥터 다운로드

레드햇 고객 포탈(http://access.redhat.com)에 접속하여 설치할 OS 플랫폼에 맞는 JBoss EAP 6의 웹 서버 커넥터 네이티브 패키지를 다운로드 합니다.

 

② HTTPD 모듈 디렉터리에 *.so 파일 복사

다운로드한 웹 커넥터 네이티브 패키지 압축을 해제합니다.

$ cd /CLOUD/JBOSS
$ unzip ~/Downloads/jboss-eap-native-webserver-connectors-6.2.0-RHEL6-x86_64.zip

 

*.so 파일을 $HTTPD_HOME/modules 디렉터리로 복사합니다.

$ cd /CLOUD/JBOSS/jboss-eap-6.2/modules/system/layers/base/native/lib64/httpd/modules
cp *.so /CLOUD/APACHE/jboss-ews-2.0/httpd/modules

 

③ mod_cluster.conf 파일 작성

jboss-eap-native-webserver-connectors-6.2.0-RHEL6-x86_64.zip 파일 내의 'jboss-eap-6.2/modules/system/layers/base/native/etc/httpd/conf' 내의 mod_cluster.conf를 참조하여 Apache HTTP 서버가 설치된 디렉터리의 conf.d 디렉터리($HTTPD_HOME/conf.d)에 mod_cluster.conf 파일을 작성합니다.

# mod_proxy_balancer should be disabled when mod_cluster is used
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule slotmem_module modules/mod_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule advertise_module modules/mod_adverties.so

MemManagerFile /var/cache/mod_cluster

<IfModule manager_module>
	Listen 6666
    <VirtualHost 127.0.0.1:6666>
    	<Directory />
        	Order deny,allow
            Allow from all
        </Directory>
        ServerAdvertise on
        AdvertiseGroup 224.0.1.105:23364
        EnableMCPMReceive
        ErrorLog logs/modcluster.log
        LogLevel info
        <Location /mod_cluster_manager>
        	SetHandler mod_cluster-manager
            Order deny,allow
            Allow from all
        </Location>
    </VirtualHost>
</IfModule>

NameVirtualHost *:80

<VirtualHost *:80>
	ProxyPass /* balancer://mycluster/* stickysession=JSESSIONID|jsessionid nofailover=On
    ProxyPassMatch ^/.*\.(jsp|do|mvc)$ balancer://mycluster/
    <Location />
    	Order Deny,Allow
        Allow from All
    </Location>
    <Location /mod_cluster_manager>
    	SetHandler mod_cluster-manager
        Order deny,allow
        Allow from all
    </Location
</VirtualHost>

 

앞 절에서 설정한 mod_jk.conf 파일이 잇으면, mod_jk.conf.bak으로 이름을 변경합니다.

 

 

④ httpd.conf 수정

conf 디렉터리로 이동합니다.

$ cd $HTTPD_HOME/conf
$ vim httpd.conf

 

httpd.conf 파일의 proxy_balancer_module을 사용하지 않도록 주석 처리되어 있는지 확인합니다.

##LoadModule proxy_balancer_module modules/mod_proxy_balancer.so

 

⑤ 웹 서버 시작

mod_cluster.conf 파일을 작성한 후 웹 서버를 시작합니다.

$ cd $HTTPD_HOME/sbin
$ sudo ./apachectl stop
$ sudo ./apachectl start

 

⑥ standalone-ha.xml 파일에서 multicast-address 변경

다른 클러스터와 충돌을 피하려고 standalone-ha.xml을 수정하여 기본 멀티캐스트 주소를 변경합니다. modcluster 소켓 바인딩에서 '${변수명:기본값}' 형식을 사용할 수 있도록 다음과 같이 변경합니다. server1, server2의 standalone-ha.xml 파일을 모두 변경합니다.

<socket-binding name="modcluster" port="0" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>

 

mod_cluster 멀티캐스트 주소를 변경하려면 server1.sh, server2,sh 파일에 '-Djboss.modcluster.multicast.address=224.10.1.1'과 같이 파라미터를 추가하면 됩니다. 같은 네트워크에 JBoss EAP 6 인스턴스가 있으면 이 설정을 꼭 사용해야 합니다.

 

⑦ JBoss EAP 인스턴스 실행

첫 번째 JBoss 인스턴스를 실행합니다(port-offset=0).

$ cd $JBOSS_HOME/server1
$ ./server1.sh

 

두 번째 JBoss 인스턴스를 실행합니다(port-offset=100).

$ cd $JBOSS_HOME/server2
$ ./server2.sh

 

⑧ mod_cluster_manager에서 연결상태 확인

웹 브라우저에서 http://localhost/mod_cluster_manager에 접속하여 mod_cluster를 이용한 연결상태를 확인합니다.

 

 

 

(3) mod_cluster 컴포넌트

설정 예제에서 보면 mod_cluster.conf 파일에서 LoadModule을 사용하여 4개의 모듈을 설정했습니다. 각 모듈이 어떤 역할을 하는지 알아봅시다.

모듈명 설명
mod_slotmem.so 공유 메모리 관리 모듈 : 공유 메모리를 사용하여 웤 노드 정보를 여러 웹 서버 프로세스에서 사용할 수 있도록 합니다.
mod_manager.so 클러스터 관리 모듈 : 워커 노드 등록과 워커 노드 부하 데이터, 애플리케이션 생명 주기 이벤트 등의 메시지를 수신하고 모니터링합니다.
mod_proxy_cluster.so 프록시 밸런서 모듈 : 클러스터 노드로 요청을 라우팅합니다. 클러스터 내의 각 노드 애플리케이션의 현재 상태 정보, 세션 ID에 따라 요청을 전달할 노드를 선택하여 전달합니다.
mod_advertis.so 프록시 Advertisement 모듈 : UDP 멀티캐스트 메시지를 사용하여 프록시 서버의 상태를 브로드캐스트합니다. JBoss EAP 인스턴스와 같은 멀티캐스트 IP를 사용하여 웹 서버와 JBoss 인스턴스 간으 ㅣ상태 정보를 파악합니다.

 

① mod_manager.so

클러스터 관리 모듈인 mod_manager는 워커 노드를 등록하고, 워커 노드의 부하상태에 대한 데이터, 애플리케이션 라이프 사이클 이벤트 등의 메시지를 수신합니다.

LoadModule manager_module modules/mod_manager.so

 

mod_manager 모듈에서 설정할 수 있는 지시어는 다음과 같습니다. 웹 서버의 Virtual-Host 지시어 안에서 사용합니다.

구분 기본값 설명
MemManagerFile /logs mod_manager가 사용하는 파일을 저장하는 위치를 지정합니다.
공유 메모리 사용을 위한 키나 락 파일이 이 위치에 저장됩니다.
절대 경로를 사용해야 합니다.
공유 디렉터리를 사용하지 말고 로컬 디스크의 위치를 사용하는 것이 좋습니다.
Maxcontext 100 mod_cluster가 사용할 컨텍스트의 최대값
Maxnode 20 mod_cluster가 사용할 워커 노드의 최대값
Maxhost 20 mod_cluster가 사용할 호스트의 최대값
로드 밸런서 최대 개수
Maxsessionid 0 저장되는 세션 ID의 최대값
5분 이내에 세션에서 받은 정보가 없으면 세션이 활성화되어 있지 않다고 판단합니다.
기본값은 0으로 비활성화 상태입니다.
ManagerBalancerName mycluster 워커 노드가 로드 밸런서의 이름을 지정하지 않은 경우에 사용하는 로드 밸런서의 이름
PersistSlot off on으로 설정하면 노드 이름과 컨텍스트가 파일에 저장됩니다.
CheckNonce on on으로 설정하면 세션 ID가 이전에 사용된 적이 있는지 확인합니다.
SetHandler   핸들러를 정의하면 클러스터의 워커 노드에 대한 정보를 표시하는 웹 페이지를 사용할 수 있습니다.
<Location /mod_cluster_manager>
   SetHandler mod_cluster-manager
   Order deny, allow
   Deny from all
   Allow from 127.0.0.1
</Location>

 

② mod_proxy_cluster.so

mod_proxy_cluster는 클러스터 노드에 요청을 라우팅합니다. 클러스터 내의 애플리케이션의 상태 정보, 세션ID 등에 따라서 전달할 노드를 선택하고, 요청을 전달합니다.

LoadModule proxy_cluster_module modules/mod_proxy_cluster.so

 

mod_proxy_cluster의 부하 분산 관련 설정은 다음과 같습니다.

항목 기본값 설명
CreateBalancers 2 웹 서버의 가상 호스트에서 로드 밸런서를 만드는 방법을 정의합니다.
0 : 웹 서버에 정의된 모든 가상 호스트에 대해서 로드 밸런서를 만듧니다.
1 : 밸런서를 만들지 않습니다.
2 : 메인 서버만 만듧니다.
UseAlias 0 정의된 이름이 ServerName과 같은지 확인합니다.
0 : 확인하지 않습니다.
1 : 일치하는지 확인합니다.
LBstatusRecalTime 5초 워커 노드의 상태를 계산하는 시간 간격을 정의합니다.

 

③ ProxyPass

ProxyPass는 원격 서버를 로컬 서버의 특정 주소에 맵핑하여 연결합니다.

ProxyPass /requested/ http://worker.test.com/

 

로컬 서버의 주소가 http://test.com을 가지고 있다면 위의 ProxyPass 지시문은 http://test.com/requested/file1의 로컬 요청을 http://worker.test.com/file1의 프록시 요청으로 변환하여 전달합니다.

 

ProxyPass를 사용하여 JBoss EAP 인스턴스들에 요청을 전달하게 설정할 수 있습니다. 다음은 모든 요청을 mycluster라는 로드 밸런서로 전달하는 설정입니다.

ProxyPass /* balancer://mycluster/*

 

백엔드 JBoss 인스턴스로 요청을 전달하지 말아야 할 경우에는 '!'를 사용합니다. 다음은 정적인 컨텐츠가 보관된 images, js, css 디렉터리 하위의 요청을 전달하지 않도록 설정한 것입니다.

ProxyPass /images !
ProxyPass /js !
ProxyPass /css !

 

특정 하위 디렉터리를 리버스 프록시하고 싶지 않을 때 '!'를 사용할 수 있습니다. 예를 들어 다음의 설정은 /mirror/foo/i를 제외한 /mirror/foo 요청을 backend.test.com에 전달합니다.

ProxyPass /mirror/foo/i !
ProxyPass /mirror/foo http://backend.test.com

 

④ ProxyPassMatch

ProxyPassMatch는 정규식을 사용하여 프록시 URL 패턴을 지정할 때 사용합니다. 단순한 문자열 비교가 아닌 정규식을 사용하는 것을 제외하고 ProxyPass와 같습니다.

ProxyPassMatch ^(/*\.gif)$ http://backend.test.com/$1

 

http://test.com/foo/bar.gif에 대한 요청을 내부적으로 http://backend.test.com/foo/bar.gif 프록시 요청으로 변환하여 전달합니다. 

 

마찬가지로 특정 확장자 패턴에 대해서 JBoss 인스턴스로 전달하지 않도록 다음과 같이 설정할 수 있습니다.

ProxyPassMatch ^(/.*\.xml)$ !
ProxyPassMatch ^(/.*\.swf)$ !

 

⑤ mod_advertise.so

mod_advertise는 UDP 멀티캐스트 메시지를 사용하여 JBoss EAP 인스턴스와 웹 서버 간의 상태를 브로드캐스트합니다. 클러스터링 멤버로 참가하고, 떠나는 것과 같은 상태 정보를 서로 알 수 있도록 설정합니다.

LoadModule advertise_module modules/mod_advertise.so

 

mod_advertise 설정 항목은 아래와 같습니다.

구분 기본값 설명
ServerAdvertise Off Advertises하는 메커니즘을 정의합니다.
On으로 설정하면 멀티캐스트를 사용하여 워커 노드에 프록시 상태 정보를 보냅니다.
ServerAdvertise On http://hostname:port/에서 호스트 이름과 포트를 지정할 수 있습니다. 이름 기반의 가상 호스트를 사용하거나 가상 호스트를 사용하지 않는 경우에 지정합니다.
AdvertiseGroup 224.0.1.105:23364 멀티캐스트 주소를 정의합니다.
'AdvertiseGroup_주소:포트'로 설정합니다.
Jboss EAP의 mod_cluster가 사용하는 멀티캐스트 IP, 포트와 같은 값을 지정합니다.
AdvertiseFrequency 10초 멀티캐스트 메시지 전송 간격을 설정합니다.
AdvertiseSecurityKey   Jboss EAP의 mod_cluster를 식별하는데 사용하는 문자열을 지정합니다.
AdvertiseBindAddress 0.0.0.0:23364 멀티캐스트 메시지를 보낼 때 사용할 바인드 주소를 정의합니다.
NIC가 여러 개 있을 경우 특정 IP 주소가 Advertise 멀티캐스트 메시지를 사용하도록 설정할 수 있습니다.

 

 

⑥ mod_cluster 서브시스템 설정

웹 관리 콘솔에서 'Profile' -> 'Web' -> 'mod_cluster'에서 mod_cluster 서브시스템을 설정할 수 있습니다. 기본적으로 ha 프로파일과 full-ha 프로파일에만 mod_cluster 서브시스템이 활성화됩니다. 스탠드얼론 서버는 standalone-ha.xml을 사용하여 서버를 시작해야 합니다. 밸런서의 이름이나, 세션, 웹 컨텍스트, 프록시, SSL 및 네트워킹을 설정할 수 있습니다.

 

웹 컨텍스트 설정에서는 JBoss EAP 6 내부적으로 사용하는 컨텍스트들에 대해서 mod_cluster에 전달되지 않도록 설정되어 있습니다. 이 컨텍스트에 루트 컨텍스트(ROOT)가 포함되어 있어, 애플리케이션에서 루트 컨텍스트를 사용하려면 다음과 같이 ROOT 컨텍스트를 사용하도록 변경해야 합니다.

[standalone@localhost:9999 / ] /subsystem=modcluster/mod-cluster-config=configuration:writeattribute(name="excluded-contexts",value="invoker,jbossws,juddi,console")
{
	"outcome" => "success",
    "response-headers" => {
    	"operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}

 

기본적으로 스티키 세션을 사용하도록 설정되어 있습니다.

 

 

⑦ mod_cluster 스티키 세션

스티키 세션을 사용하려면 JBoss EAP 뿐만 아니라 웹 서버의 mod_cluster 설정도 필요합니다. 다음과 같이 ProxyPass에서 stickysession을 설정합니다.

ProxyPass /* balancer://mycluster/* sticksession=JSESSIONID|jsessionid nofailover=On
ProxyPassMatch ^/.*\.(jsp|do|mvc)$ balancer://mycluster/

 

 

 

참고 서적 : 거침없이 배우는 JBoss

반응형

댓글