본 장에서는 EJB 엔진에 대한 기초적인 사항과 JEUS EJB의 최상위 레벨의 개념인 구조, 설정, 운영, 모니터링과 튜닝에 대해 설명한다.
EJB 엔진은 EJB의 운영 환경을 제공한다. EJB 표준에서는 EJB Container라는 용어가 사용되고 있으며, 본 안내서에서 사용한 EJB 엔진과 동일한 개념이다. EJB 모듈, EJB 디플로이에 대한 상세한 정보는 “제3장 EJB 모듈”과 “제4장 EJB의 공통 특성”을 참고한다.
다음은 EJB 엔진의 주요 기능에 대한 설명이다.
EJB 엔진과 엔진 컨테이너
하나의 엔진 컨테이너에는 하나의 EJB 엔진만 존재할 수 있다. 그러나 한 노드에는 여러 개의 엔진 컨테이너가 존재할 수 있기 때문에 한 노드에서는 여러 개의 EJB 엔진이 존재할 수 있다.
일반적으로 여러 개의 머신이나 CPU 위에 여러 개의 엔진 컨테이너와 EJB 엔진이 설정되어 실행된다. 이러한 설정을 EJB 클러스터링이라고 한다. 이 구조는 시스템의 성능 향상과 높은 안정성 및 보안성을 유지해주는 효율적인 시스템 구조이다. EJB 클러스터링에 관한 자세한 내용은 “제6장 EJB 클러스터링”을 참고한다.
EJB 엔진 기본 설정
EJB 엔진의 설정 파일은 EJBMain.xml이다. 자세한 내용은 “2.4. EJB 엔진 설정”을 참고한다.
EJB 엔진 Logging
JEUSMain.xml의 설정에 따라 노드와 컨테이너에 로그를 남길 수 있지만 특별히 EJB 엔진의 로그만 별도로 남길 수 있다. 이때 EJB 엔진 로그를 별도로 남기게 되더라도 노드나 컨테이너 로그에도 EJB 엔진 로그가 남는다.
로거의 핸들러에 파일 핸들러가 지정되면 다음의 로그 파일이 생성된다.
JEUS_HOME\logs\<node name>\<node name>_<container name>\ejb\error(_yyyymmdd_hh).log
“_yyyymmdd_hh”는 로그 파일이 생성된 날짜와 시간을 나타내고 <valid-day>,<valid-hour> 설정에 따라 붙을 수도 있고 붙지 않을 수도 있다. EJB 엔진이 서비스를 제공하는 동안 날짜 또는 시간별로 다른 로그 파일이 생성되는 것을 원하면 <valid-day>,<valid-hour>를 설정해야 한다.
뿐만 아니라 콘솔 핸들러를 사용하면 모든 로그 메시지를 화면에 남길 수도 있다. 일반적으로 이런 상황에서는 로그 메시지가 파이프를 통하여 JEUS Manager가 시작된 command line에 출력된다.
그 외에 사용자가 만든 사용자 핸들러를 등록할 수 있다. 자세한 설명은 “JEUS Server 안내서”의 “제11장 Logging”을 참고한다.
Active Management는 EJB 모듈에 문제가 발생한 경우에 EJB 엔진이 전자우편으로 자체적으로 통지를 보내주는 기능이다.
예를 들어, Bean 클래스의 잘못된 구현으로 인해서 무한 루프에 빠지거나 Deadlock과 같은 심각한 오류가 발생했을 때 EJB 엔진이 이를 감지하여 통지를 보내주도록 되어 있다. 부가적으로 오류 처리 정책을 설정할 수가 있어서 비정상적인 현상이 발생했을 경우에 전자우편 통지뿐만 아니라 해당 EJB 엔진이 동작하는 엔진 컨테이너를 자동으로 재시작시킬 수도 있다.
Active Management에 대한 자세한 설정은 “2.4. EJB 엔진 설정”을 참고한다.
원격 클라이언트가 JNDI 서비스를 통해서 EJB 인스턴스를 찾을 때 클라이언트는 EJB 메소드를 호출할 수 있는 RMI Stub을 받는다. 기본적으로 Stub은 RMI 런타임을 통해서 EJB와 원격 통신이 이루어지며, RMI 통신은 TCP 소켓을 기반으로 하고 있다. 이 방식은 RMI 통신 포트를 따로 필요로 하기 때문에 방화벽이 있는 환경에선 문제가 될 수 있다. 이 경우 특별한 통신 모드가 필요한데 이것이 HTTP Invoke Mode이다.
이 모드를 사용할 경우 원격 클라이언트의 RMI 요청을 HTTP로 감싸서 웹 컨테이너로 보내고 웹 컨테이너는 RMI 요청을 다루는 서블릿(jeus.rmi.http.ServletHandler)으로 요청을 전달한다. 이 서블릿은 RMI 런타임으로 요청을 전달해서 실제 EJB 메소드를 호출한 뒤 그 결과를 HTTP 응답으로 감싸서 원격 클라이언트로 전달한다. HTTP Invoke Mode는 EJB 엔진 또는 EJB 컴포넌트 별로 설정할 수 있다.
EJBMain.xml에 HTTP Invoke Mode가 설정되면 EJB 엔진 내의 모든 모듈에 적용된다. EJB 모듈의 jeus-ejb-dd.xml에서는 특정 EJB 컴포넌트에만 적용할 수 있다. 이때 jeus-ejb-dd.xml의 설정이 EJBMain.xml의 설정보다 우선한다.
EJBMain.xml과 jeus-ejb-dd.xml 설정에 관한 자세한 내용은 “2.4.5. HTTP Invoke 환경설정”을 참고한다.
다음은 EJB 엔진을 관리할 때 사용하게 되는 디렉터리와 파일의 목록이다.
기본 디렉터리에 대한 내용은 “1.3.1. 디렉터리 구조”와 동일하고, 다음은 EJB
엔진에서 주로 사용하는 내용에 대한 설명이다.
EJB 엔진을 관리하는 툴이 위치한 디렉터리이다.
툴 | 설명 |
---|---|
appcompiler | EJB를 디플로이하기 위해 필요한 클래스를 생성하고 컴파일해서 Fast Deploy를 하게 한다. |
jeusadmin | EJB 엔진을 제어하고 모니터링하기 위해 사용된다. |
파일명 | 설명 |
---|---|
JEUSMain.xml | JEUS 시스템에 새로운 EJB 엔진을 추가하는 경우 사용된다. |
EJBMain.xml | JEUS의 EJB 엔진의 주 설정 파일이다. |
EJB 엔진 로그 파일이 저장된다.
로그 파일은 다음과 같은 포맷으로 명명된다. “_yyyymmdd_hh”는 로그 파일이 생성된 날짜와 시간을 의미하고 파일 핸들러의 설정에 따라 붙을 수도 있고 붙지 않을 수도 있다.
error_yyyymmdd_hh.log
JEUS 시스템의 EJB 엔진을 추가하고 설정하기 위해서는 다음 파일에 설정 데이터를 입력해야 한다.
기본적으로 WebAdmin을 이용하면 쉽게 설정할 수 있으나 XML을 직접 수정하는 사용자를 위해 다음 절에서 각 파일에 대한 필수 설정 및 옵션 설정에 대한 설명과 함께 XML 예제를 설명한다.
다음은 'engine1'이라는 EJB 엔진을 추가하는 간단한 예이다. 예제에서는 필수 XML 헤더가 생략되어 있다. 포함되어야 할 헤더의 정보는 “제1장 EJB 소개”를 참고한다.
[예 2.1] EJB 엔진 추가 : <<JEUSMain.xml>>
<jeus-system> . . . <node> . . . <engine-container> . . . <engine-command> <type>ejb</type> <name>engine1</name> <system-logging> <handler> <file-handler> <name>fileHandler</name> <level>FINEST</level> <file-name>ejbengine1.log</file-name> <valid-hour>1</valid-hour> </file-handler> </handler> </system-logging> </engine-command> . . . </engine-container> . . . </node> . . . </jeus-system>
<engine-command> 태그를 JEUS가 기동할 때 정상적으로 작동하게 하려면 다음의 디렉터리가 반드시 존재해야 한다.
JEUS_HOME\config\<node name>\<node name>_ejb_<engine name>
항목 | 설명 |
---|---|
<node name> | JEUS의 노드 이름이고, 이는 로컬 머신의 호스트 이름(vhost.properties를 설정을 한 경우는 가상 노드 이름)을 의미한다. |
<engine name> | JEUSMain.xml의 <engine-command> 태그 중 <name> 태그의 값을 가지고 있어야 한다. 위의 예에서 호스트 이름이 'johan'이라고 가정하면, 디렉터리 이름은 'johan_ejb_engine1'이 된다. |
위 디렉터리 아래에는 반드시 EJBMain.xml이 존재해야 한다.
1. 하나의 엔진 컨테이너에는 하나의 EJB 엔진만 설정할 수 있다. JEUSMain.xml에 EJB 엔진을 추가하는 자세한 방법은 “JEUS Server 안내서”의 “제2장 JEUS 설정”을 참고한다.
2. WebAdmin을 사용하여 엔진을 설정하는 방법에 대해서는 WebAdmin의 온라인 도움말을 참고한다.
EJBMain.xml은 EJB 엔진의 모든 운영 설정들을 포함하고 있으며, 엔진의 홈 디렉터리에 위치한다(이를 엔진 디렉터리라고 한다). 디렉터리를 설정하는 항목에 대한 설명은 이전의 설명을 참고한다.
다음은 EJB 엔진을 설정하는 EJBMain.xml의 예로 <ejb-engine> 태그에 설정한다.
[예 2.2] EJB 엔진 설정 : <<EJBMain.xml>>
<ejb-engine> <resolution>100000</resolution> <enable-user-notify>true</enable-user-notify> <active-management> . . . </active-management> <invoke-http> . . . </invoke-http> </ejb-engine>
다음은 설정 태그에 대한 설명이다.
태그 | 설명 |
---|---|
<resolution> | 설정된 값은 ms(millisecond) 단위로 active management의 체크 주기와 passivation 체크 주기이다. 즉, Block된 스레드를 감지하는 주기와 passivation 타임아웃동안 클라이언트로부터 요청을 받지 않은 Bean을 감지하는 주기이다. |
<enable-user-notify> | 옵션을 설정하면 EJB Exception이 JEUSMain.xml에서 설정한 user log에 남게 된다. user log에 대한 설명은 “JEUS Server 안내서”의 “제11장 Logging”을 참고한다. |
<active-management> | EJB 엔진을 모니터링하고, 오류를 처리하며 전자우편 통보와 관련된 설정을 한다. |
<invoke-http> | EJB RMI Stub이 RMI 런타임 포트를 접근할 수 없는 상황에 사용한다. 자세한 내용은 “2.4.5. HTTP Invoke 환경설정”을 참고한다. |
<timer-service> | “제10장 EJB Timer Service”에서 설명한다. |
Active Management 설정은 엔진 재시작 조건들과 전자우편 통보 기능으로 나누어져 있다. 엔진 재시작 조건은 EJB 엔진이 재시작하기 전까지의 허용 가능한 최대 Block된 EJB 스레드 수로 결정된다.
다음은 Active Management 설정하는 EJBMain.xml의 예로 <active-management> 태그에 해당 정보를 설정한다.
[예 2.3] Active Management 설정 : <<EJBMain.xml>>
<ejb-engine> . . . <active-management> <max-blocked-thread>200</max-blocked-thread> <max-idle-time>180000</max-idle-time> <email-notify> <name>activeHandler</name> <smtp-host-address>mail.foo.com</smtp-host-address> <from-address>jeus@foo.com</from-address> <to-address>admin@foo.com;admin2@foo.com</to-address> <cc-address>admin@bar.com</cc-address> <bcc-address>admin2@foo.com</bcc-address> </email-notify> </active-management> . . . </ejb-engine>
다음은 설정 태그에 대한 설명이다.
EJB 엔진의 system logging과 user logging은 JEUSMain.xml에서 설정된다. 이 설정은 EJB 엔진뿐만 아니라 다른 모든 엔진에도 적용되는 공통적인 설정이므로 “JEUS Server 안내서”의 “제11장 Logging”을 참고한다.
HTTP Invoke 환경설정은 EJB의 RMI Stub이 자동으로 HTTP 프로토콜로 RMI 핸들러 서블릿을 호출하여 이 서블릿이 RMI 런타임에 클라이언트의 요청을 전달한다. 이는 JEUS_HOME/webhome/system_app/rmiHandlerServlet.war로 제공되므로 <invoke-http>에 설정된 URL과 동일하게 디플로이한다.
EJB 엔진에서 HTTP Invocation이 필요하면 EJBMain.xml에서 <invoke-http>를 추가한다. EJBMain.xml의 설정은 모든 모듈에 적용되는데, 각각의 모듈의 DD파일에 <invoke-http>가 있다면 이것이 EJBMain.xml의 설정을 무시하게 된다.
다음은 HTTP Invoke 환경설정에 대한 EJBMain.xml의 예이다.
[예 2.4] HTTP Invoke 환경설정 : <<EJBMain.xml>>
<ejb-engine> . . . <invoke-http> <url>/rmiHandlerServlet/ServletHandler</url> <http-port>80</http-port> </invoke-http> </ejb-engine>
다음은 설정 태그에 대한 설명이다.
<url>
RMI Stub으로부터 호출되는 RMI 핸들러 서블릿의 URI를 입력한다.
URI에서는 프로토콜, IP 주소, 포트를 제외한 서블릿 요청 경로만을 넣는다. 즉, rmiHandlerServlet.war의 jeus-web-dd.xml에 설정한 <contex-path>( jeus-web-dd.xml을 따로 생성하지 않으면 <contex-path>의 기본값인 war 이름이다. 예에서는 'rmiHandlerServlet'이 된다)와 web.xml에 설정한 <url-pattern>을 이어서 입력한다.
프로토콜은 “HTTP”로 IP 주소는 RMI 런타임과 동일한 주소로 간주된다. HTTP-RMI 요청을 받은 웹 서버와 웹 컨테이너가 RMI 런타임과 같은 머신에 있어야 한다. 그러면 RMI 런타임의 주소는 RMI Stub에게 알려지게 된다. 웹 서버의 포트는 반드시 다음 <http-port>에 설정해야 한다.
JEUS에서 제공하는 rmiHandlerServlet.war에는 jeus-web-dd.xml이 포함되어 있지 않다. 따라서 기본적으로 context는 모듈 이름과 같은 rmiHadlerServlet을 사용하게 된다. 또한 web.xml에는 <url-pattern>이 서블릿 핸들러가 설정되어 있다. 기본값 외의 설정을 사용하고 싶은 경우에는 jeus-web-dd.xml을 생성하고 web.xml를 수정한 후 rmiHandlerServlet.war를 디플로이한다.
<http-port>
HTTP-RMI 요청을 받고 처리할 웹 서버 또는 웹 컨테이너를 설정한다.
웹 서버/웹 컨테이너는 반드시 RMI 핸들러 서블릿이 디플로이되어 실행되고 있어야 한다.
EJB 엔진의 XML 설정 외에 JEUSMain.xml의 <engine-container><command-option> 태그의 JAVA_ARGS에 -D 옵션을 추가하여 시스템 프로퍼티를 설정할 수 있다.
자세한 내용은 "JEUS Reference Book"을 참고한다.
EJB 엔진을 제어하는 것은 다른 JEUS 엔진(서블릿 또는 JMS 엔진)을 제어하는 것과 많은 유사점을 가진다. 콘솔 툴(jeusadmin)을 이용하거나 WebAdmin을 사용하면 EJB 엔진의 실행 환경의 정보와 상태 정보를 모니터링할 수 있다.
1. WebAdmin을 사용하여 EJB 엔진을 모니터링할 것을 권장한다. WebAdmin이 콘솔 툴에 비해 자세하고 완벽한 엔진 상태 정보를 제공한다. WebAdmin에 대한 자세한 내용은 "JEUS WebAdmin 안내서"를 참고한다.
2. 콘솔 툴(jeusadmin)로 기본적인 실행 환경 정보를 얻을 수 있다. 더 자세한 내용은“JEUS Reference Book”의 “4.2.4. EJB 엔진 관련 명령어”를 참고한다.
EJB 엔진의 전체적인 성능 향상을 위해 설정을 변경할 수 있다. 본 절에서는 EJB 엔진(EJBMain.xml에 설정된)의 성능관련 설정을 간략하게 설명한다.
튜닝을 위해 필요한 사항은 다음과 같다.
Resolution 설정 튜닝
Fast-Deploy 기능 사용
최대성능을 위한 시스템 로그 설정
Active Management 사용하지 않기
HTTP invoke 모드 사용
EJBMain.xml의 정보나 팁에 대해서는 "JEUS XML Reference"의 "13. EJBMain.xml EJB 엔진 설정"을 참고한다. XML/Schema 중 “P”라고 적힌 것은 성능과 관련된 것이다.
Resolution은 EJB 엔진의 상태를 체크하는 주기로 2가지 주기로 사용된다.
Block된 스레드 개수가 몇 개인지 검사한 후 EJB 엔진을 재시작하는 Active management의 체크 주기를 나타낸다.
모든 하위 컴포넌트들(예: Bean pool)을 점검하고, 각 Bean이 비활성화 대상인지 검사하는 passivation의 체크 주기를 나타낸다.
이 값이 클수록 시스템 메모리나 기타 리소스의 회수 주기가 길어져 자원 활용률은 떨어지지만 이에 대한 작업 수행이 덜 발생하므로 엔진의 성능은 향상된다. 이 값을 작게 하면 엔진은 최신 상태를 유지하겠지만 전체적인 성능은 저하된다. 따라서, 메모리 크기나 용도에 따라서 이 값을 적절하게 설정하는 것이 매우 중요하다.
Resolution값의 설정에 따라 <passivation-timeout>이나 <disconnect-timeout>이 원하는 때에 발생하지 않을 수 있으므로 주의해야 한다.
Fast Deploy 옵션은 EJBMain.xml에서 설정하지 않고 애플리케이션별로 설정하는 것이지만 성능에 큰 영향을 미친다.
엔진이 기동될 때 디플로이되어야 할 EJB 모듈들이 이미 컴파일되어 RMI Stub과 Skeleton이 있다면 애플리케이션의 jeus-ejb-dd.xml이나 jeus-application-dd.xml에서 <fast-deploy> 옵션을 true로 설정한다. 이는 엔진이 EJB 모듈을 디플로이할 때 RMI 클래스를 생성하지 않도록 하는 것이다.
EJB 모듈과 Deploy에 관련된 보다 자세한 정보는 “제3장 EJB 모듈”을 참고한다.
시스템 로그는 성능 개선을 위해 3가지 방법으로 조정 가능하다.
가능하면 파일 핸들러를 사용해서 logging이 빠르게 이루어지도록 하는게 좋다.
파일 핸들러의 버퍼 크기를 크게 설정한다.
로그 레벨을 “SEVERE”로 설정한다.
위의 제안은 안정적인 운영 환경에서만 적용되어야 한다. 개발 환경에서는 “반대”의 값들이 설정되어야 한다. 즉, 콘솔 핸들러를 사용하고, 작은 버퍼 크기를 사용하고, “FINE” 로그 레벨을 사용하는 것이 개발을 용이하게 한다.
EJB 엔진 레벨에 Active Management를 사용하는 것이 반드시 필요한 것은 아니다. 설정에 따라 성능 저하를 가져올 수 있기 때문에 기본적으로는 사용하지 않는다. 대신 서블릿 엔진에 정의된 Active Management를 사용하는 것이 편리하다. 그러므로 대부분 EJBMain.xml에서 Active Management 설정을 생략하는 경우가 많다.