제3장 JEUS 제어 및 모니터링

내용 목차

3.1. JEUS 제어 및 모니터링
3.1.1. JEUS Manager 기동과 종료
3.1.2. 노드 제어 및 모니터링
3.1.3. 엔진 컨테이너의 제어 및 모니터링
3.1.4. 엔진 제어 및 모니터링
3.2. Thread 모니터링 및 제어
3.2.1. Thread 모니터링
3.2.2. Thread 제어

본 장에서는 Command Line에서 JEUS를 제어하고 모니터링 하는 방법을 설명한다. 설명한 내용은 WebAdmin을 통해서도 할 수 있으므로 Command Line에 익숙하지 않다면 WebAdmin을 사용할 것을 권장한다.

참고

jeus와 jeusadmin 콘솔 툴에 관한 자세한 사항은 JEUS Reference Book”의 “제3장 jeus”JEUS Reference Book”의 “4.2.3. 공통 명령어”를 참조한다. WebAdmin을 이용한 JEUS Manager 컨트롤은 "JEUS WebAdmin 안내서"를 참조한다.

3.1. JEUS 제어 및 모니터링

3.1.1. JEUS Manager 기동과 종료

JEUS Manager는 jeus 실행 스크립트에 의해서 일반적인 형태로 실행된다.

JEUS Manager 기동

  1. JEUS Manager를 실행하여 대기 상태가 되도록 하기 위해서는 JEUS_HOME\bin\ 경로가 시스템 경로로 설정되어 있거나 해당 디렉터리로 이동 후 실행해야 한다.

    c:\jeus\bin> jeus
    [2013.10.30 17:36:22][0][b392] [johan-1] [MGR-0000] JEUS Server is starting - JEUS 6.0 (Fix#9) (6.0.0.9-b392)
    . . .
    [2013.10.30 17:36:22][0][b392] [johan-1] [MGR-0006] virtual host name=[johan]
    . . .
    [2013.10.30 17:36:23][2][b392] [johan-1] [MGR-0173] JNDI Naming Server started
    . . .
    [2013.10.30 17:36:26][0][b392] [johan-1] [MGR-0248] JEUS Manager is READY

    "Jeus Manager is Ready"라는 로그가 출력되면 성공적으로 JEUS Manager가 Started 상태가 된 것이다.

  2. 다음의 예제는 jeusadmin 툴을 'johan'이라는 노드에 접근하도록 실행하는 방법이다. 사용자 ID와 패스워드를 입력한다.

    jeusadmin johan
    Login name>administrator
    Password>
  3. 다른 콘솔에서 jeusadmin 명령을 실행해서 JEUS Manager를 기동한다.

    johan>boot 
  4. JEUS Manager 창에 기동 관련 정보들이 표시되고, 작업이 성공적으로 끝나면 jeusadmin 창에 다음의 메시지가 출력된다.

    johan boot done
    johan_container1

    jeusadmin 창의 마지막에 출력된 메시지는 'johan_container1'라는 엔진 컨테이너가 동작하기 시작했다는 내용이며, 그것은 JEUS Manager가 현재 정상적으로 동작하고 있다는 의미이다.

위와 같이 jeusadmin을 통해 JEUS Manager를 기동할 수도 있지만 jeus 실행 스크립트에 사용자 ID와 패스워드를 입력하면 한번에 기동할 수 있다.

c:\jeus\bin> jeus -Uadministrator -P<password>
. . .
[2013.10.30 17:45:59][0][b392] [johan-1] [MGR-0248] JEUS Manager is READY
. . .
[2013.10.30 17:46:08][2][b392] [container1-1] [MGR-0103] engine container
[johan_container1] is READY
[2013.10.30 17:46:08][2][b392] [container1-1] [MGR-0101] currently running engines 
of engine container[johan_container1] : [johan_jms_engine1, johan_servlet_engine1,
 johan_ejb_engine1]
[2013.10.30 17:46:08][0][b392] [johan-54] [MGR-0303] engine container[johan_container1] 
initialization successfully done [pid : 2000]
[2013.10.30 17:46:08][0][b392] [johan-1] [MGR-0242] JeusServer one-step booting successful 
: [johan_container1, johan_container2]

참고

하나 또는 몇몇 엔진 컨테이너가 기동되지 않았다고 하더라도 JEUS Manager는 노드가 정상적으로 기동되었다고 판단한다.

JEUS Manager 종료

다음의 과정으로 JEUS Manager를 종료한다.

  1. 기동 상태인 JEUS Manager를 종료하는 경우 jeusadmin에서 다음의 명령을 실행한다.

    node-name> down
  2. 다음 메시지는 종료 명령이 성공적으로 수행되어 JEUS Manager가 대기상태가 되었을 때 표시되는 메시지이다.

    The JEUS node [johan] is down.

JEUS Manager를 완전히 종료(not existing)하기 위해서는 jeusadmin에서 다음의 명령을 수행한다.

node-name> jeusexit

3.1.2. 노드 제어 및 모니터링

노드 기동

  • 노드와 구성 요소 시작

    jeusadmin 콘솔 툴에서 boot 명령을 사용하여 노드와 하위 구성 요소들을 시작할 수 있다.

    johan>boot
    johan boot done
    johan_container1
    johan_container2
  • 클러스터된 모든 JEUS 기동

    클러스터된 모든 JEUS를 기동하는 경우 -all 옵션을 사용한다.

    johan>boot -all
    johan:johan_default boot done
    johan2:johan2_default boot done

노드 종료

  • JEUS 정지

    JEUS를 정지하는 경우 down 명령을 이용한다.

    johan>down
    Do you really want to shutdown the node [johan]? (y : n):>y
    The JEUS node [johan] is down.

    위와 같이 물어보지 않도록 하려면 -i 옵션을 사용한다.

    johan>down -i
    The JEUS node [johan] is down.
  • JEUS 종료

    JEUS를 종료하는 경우 jeusexit 명령을 이용한다.

    johan>jeusexit
    johan jeusexit successful
  • JEUS 정지와 종료

    정지(down)과 종료(jeusexit)를 한 번에 하려면 down 명령에서 -e 옵션까지 설정하거나 jeusexit를 사용한다.

    johan>down -i -e
    johan down successful
    johan jeusexit successful

참고

명령어에 대한 보다 자세한 정보와 jeusadmin의 수행에 대한 내용은 JEUS Reference Book”의 “4.2.3. 공통 명령어”를 참고한다.

노드 모니터링

  • 노드 목록 조회

    jeusadmin에서 nodelist 명령을 사용하여 현재 JEUS 클러스터에 활성 중인 노드들의 목록을 얻는 것으로 시작한다.

    johan>nodelist
    johan
    johan2

    모니터링할 노드를 선택하여 jeusadmin을 통해 연결한다.

    c:\jeus>jeusadmin johan -Ujeus -Pjeus
    JEUS 6.0 (Fix#9) administration tool
    johan>
  • 특정 노드의 상태와 하위 구성 요소의 정보 조회

    pidlist와 같은 “<xyz>list” 명령을 특정 노드의 상태와 활성중인 하위 구성 요소의 정보를 얻기 위해 사용한다.

    johan>pidlist
    node or container : johan, pid : 2428
    node or container : johan_container1, pid : 2000

참고

명령들에 대한 보다 자세한 정보와 jeusadmin의 수행에 대한 내용은 JEUS Reference Book”의 “4.2.3. 공통 명령어”를 참고한다.

3.1.3. 엔진 컨테이너의 제어 및 모니터링

엔진 컨테이너 제어

  • 엔진 컨테이너 시작

    jeusadmin에서 비활성화된 엔진 컨테이너를 시작하기 위해서 startcon 명령을 사용한다.

    johan>startcon
    johan_container1 : READY
    
    johan>startcon johan_container1
    Succeeded to start johan_container1.
  • 엔진 컨테이너 정지

    활성화된 엔진 컨테이너를 정지시키기 위해 downcon 명령을 사용할 수 있다.

    johan>downcon
    johan_container1 : SHUTDOWN
    
    johan>downcon -node johan
    johan_container1 : SHUTDOWN
    
    johan>downcon johan_container1
    johan_container1 container is down successful

엔진 컨테이너 모니터링

  • 엔진 컨테이너 목록 조회

    jeusadmin에서 conlist 명령을 수행하여 활성화된 엔진 컨테이너 목록을 조회할 수 있다.

    johan>conlist
    Engine container list of the node johan
            [1] johan_container1 : READY
            [2] johan_container2 : READY
  • 엔진 컨테이너 엔진 이름 조회

    englist 명령을 통해 특정 엔진 컨테이너에 속한 엔진들의 모든 이름을 조회할 수 있다.

    johan>englist
    ========================================
    engines in the container johan_container2
    johan_servlet_engine2
    johan_ejb_engine2
    ========================================
    ========================================
    engines in the container johan_container1
    johan_servlet_engine1
    johan_ejb_engine1
    ========================================
    
    johan>englist johan_container1
    johan_servlet_engine1
    johan_ejb_engine1

참고

명령어에 대한 자세한 설명은 JEUS Reference Book”의 “4.2.3. 공통 명령어”를 참고한다.

3.1.4. 엔진 제어 및 모니터링

엔진 제어

  • 엔진 시작과 정지

    jeusadmin에서 하나의 엔진을 시작하거나 정지하기 위하여 해당 컨테이너를 시작하거나 정지해야 한다. 이때에는 컨테이너에 있는 모든 엔진들이 함께 시작하거나 정지한다.

    johan>startcon johan_container1
    Succeeded to start johan_container1.
    johan>downcon johan_container1
    johan_container1 : SHUTDOWN

    엔진들은 엔진 컨테이너가 시작될 때 자동으로 시작된다. 엔진 컨테이너는 또한 JEUS 노드가 jeusadmin에서 boot 명령을 통해서 기동될 때 자동으로 시작된다. 또한 노드나 엔진 컨테이너를 종료할 때도 같이 적용이 된다.

참고

명령어에 대한 자세한 설명은 JEUS Reference Book”의 “4.2.3. 공통 명령어”를 참고한다.

엔진 모니터링

  • 현재 노드에서 활성화된 엔진 목록 조회

    콘솔 툴(jeusadmin)을 이용하여 엔진을 모니터하기 위해 allenglist 명령만을 사용할 수 있다. 이것은 현재 노드에서 활성화된 엔진 목록을 출력한다.

    johan>allenglist
    ========================================
    engines in the container johan_contianer1
    johan_ejb_engine1
    johan_servlet_engine1
    ========================================

3.2. Thread 모니터링 및 제어

JEUS에서는 서블릿 Thread와 EJB 리모트 Thread, 시스템 Thread Pool에 대한 모니터링 기능과 Thread의 Stack을 확인할 수 있는 기능, 그리고 특정 Thread에 interrupt 시그널을 보낼 수 있는 기능을 제공한다.

3.2.1. Thread 모니터링

JEUS에서는 Thread를 모니터링하는 기능을 제공한다. 모니터링의 대상이 되는 Thread는 서블릿 요청 Thread, EJB 리모트 요청 Thread 그리고 시스템 Thread Pool이다.

서블릿 Thread나 EJB 리모트 요청 Thread의 모니터링 기능을 사용하면 Thread ID, Thread 이름, Thread 상태, 처리시간 등의 정보를 알 수 있고, Thread Pool 모니터링 기능을 사용하면 시스템 Thread Pool의 core size, max size, keep alive time, 그리고 시스템 Thread Pool에 있는 Thread 정보를 알 수 있다.

참고

단, JEUS 콘솔 툴에서는 서블릿 요청 Thread와 EJB 리모트 요청 Thread만 모니터링할 수 있다.

  • Thread 정보 확인

    콘솔 툴에서 Thread 정보를 확인하는 방법이다.

    johan>ti
    
    Thread information for [johan_container1] container
    ========================================================================
    servlet threads for 'http1' listener
    
    ------------------------------------------------------------------------
    | tid |      name |   state | elapsed |                            uri |
    ------------------------------------------------------------------------
    |  72 | http1-w00 | waiting |    9859 |                                |
    |  73 | http1-w01 | waiting |   23828 |                                |
    |  74 | http1-w02 | waiting |   23828 |                                |
    |  75 | http1-w03 | waiting |   23828 |                                |
    |  76 | http1-w04 | waiting |   23828 |                                |
    |  77 | http1-w05 | waiting |   23828 |                                |
    |  78 | http1-w06 | waiting |   23828 |                                |
    |  79 | http1-w07 |  active |    2265 | /examples/ClusteredEJBCall.jsp |
    |  80 | http1-w08 | waiting |   23828 |                                |
    |  81 | http1-w09 | waiting |   23828 |                                |
    ------------------------------------------------------------------------
    
    elsapsed: elapsed time (ms)
    ========================================================================
    =============================================================
    -------------------------------------------------------------
    |                 | total | active | idle | blocked | recon |
    -------------------------------------------------------------
    | num. of threads |    10 |      1 |    9 |       0 |     0 |
    -------------------------------------------------------------
    
    total = active + idle, recon: reconnecting
    =============================================================
    
    ==================================================================================
    EJB RMI threads
    
    ----------------------------------------------------------------------------------
    | tid |                                              name |  state | active_time |
    ----------------------------------------------------------------------------------
    |  84 | RMI TCP Connection(1)-192.168.x.x [container1-15] | active |        2297 |
    ----------------------------------------------------------------------------------
    
    active_time: time after thread created (ms)
    ==================================================================================
    ===========================================
    -------------------------------------------
    |                 | total | active | idle |
    -------------------------------------------
    | num. of threads |     1 |      1 |    0 |
    -------------------------------------------
    
    total = active + idle
    ===========================================
  • 특정 Thread의 stack trace 조회

    콘솔 툴에서 특정 Thread의 stack trace를 조회하는 방법이다. 주로 Thread 정보를 보는 명령(콘솔 툴에서의 ti 명령)을 통해 보았을 때 블록된 Thread가 있을 경우 해당 Thread의 Stack을 확인하는 데 사용한다.

    johan>strace 79
    servlet thread [tid=79] Stack trace
      at java.net.SocketInputStream.socketRead0(Native Method)
      at java.net.SocketInputStream.read(SocketInputStream.java:129)
      . . .
      at jeus.ejb.client.RemoteBusinessHomeClientHandler.create(RemoteBusinessHome
    ClientHandler.java:76)
      at jeus.ejb.client.BusinessObjectFactory.getObjectInstance(BusinessObject
    Factory.java:102)
      at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
      . . .
      at jeus.jndi.JEUSFailoverContext.lookup(JEUSFailoverContext.java:270)
      at javax.naming.InitialContext.lookup(InitialContext.java:392)
      at jeus_jspwork._600_ClusteredEJBCall_5fjsp._jspService(_600_Clustered
    EJBCall_5fjsp.java:67)
      at jeus.servlet.jsp2.runtime.HttpJspBase.service(HttpJspBase.java:106)
      . . .
      at jeus.servlet.engine.HttpRequestProcessor.run(HttpRequestProcessor.java:278)

참고

1. JEUS 콘솔 툴의 ti 명령과 strace 명령에 대한 자세한 정보는 JEUS Reference Book”의 “4.2.3. 공통 명령어”를 참조한다.

2. WebAdmin을 이용한 서블릿 요청 Thread와 EJB 리모트 요청 Thread 정보와 stack trace는 WebAdmin의 "JEUS 모니터링"의 "요청 Thread 모니터링"에서 확인할 수 있다. JEUS WebAdmin에서는 이 외에도 "JEUS 모니터링"의 "Thread Pool 모니터링"에서 시스템 Thread Pool의 정보와 시스템 Thread Pool의 Thread 정보를 확인할 수 있다. 더 자세한 사항은 "JEUS WebAdmin 안내서"와 온라인 도움말을 참조한다.

3.2.2. Thread 제어

JEUS에서는 특정 Thread에 interrupt 시그널을 보내어 수행 중인 작업을 중단할 수 있도록 Exception을 발생시키는 기능이 있다.

주의

이 기능은 현재는 실험적으로 제공되는 기능으로 Thread에 interrupt가 걸려 있으면 수행 중인 Thread가 바로 중단되는 것이 아니라 interrupt status를 체크하여 Exception을 던져 더이상 진행하지 않도록 유도하는 것이기 때문에 발생하는 Exception에 대해서는 사용자 애플리케이션에서 처리해야 한다. Exception을 제대로 처리하지 않아서 발생하는 문제에 대해서는 사용자에게 책임이 있다.

Thread interrupt

Thread에 interrupt를 건다는 것은 동작하고 있는 Thread에 interrupt 시그널을 보내서 현재 진행 중인 동작의 중단을 유도하기 위해 Exception을 발생시켜 이후의 작업을 더이상 진행하지 않도록 힌트를 주는 것이다. 주로 요청이 블록되어 있거나, 예상한 시간보다 오래 지체되어 있는 경우에 사용될 수 있다.

실제로 Thread에 interrupt가 걸린다고 해서 해당 Thread가 강제적으로 멈춘다든가, interrupt를 발생시키는 순간에 바로 효과가 있는 것은 아니다.

JEUS에서는 서블릿 Thread, EJB 리모트 요청 Thread와 시스템 Thread Pool의 수행 중인 Thread에 interrupt 시그널을 보낼 수 있는 기능을 지원한다. 이때 Thread가 JNDI 원격 커넥션이나 EJB operation, JDBC operation, 또는 IO작업을 진행 중이면 interrupt가 걸릴 수 있다.

  • 서블릿 Thread

    서블릿 Thread는 다음의 경우들에 대해 interrupt가 걸려 있으면 Exception이 발생한다. 이때 발생하는 Exception에 대한 처리는 사용자 애플리케이션에서 해야 한다.

    • JNDI 원격 커넥션을 맺으려고 할 때

    • JNDI 원격 operation을 수행하려고 할 때

    • EJB 호출하려고 할 때

    • JDBC 커넥션을 얻어올 때 또는 커넥션 객체의 메소드를 호출할 때

    jeusadmin이나 WebAdmin을 통해 관리자가 직접 interrupt를 걸 수 있으며, 서블릿 Thread의 수행시간을 체크하여 자동으로 interrupt 되도록 하는 기능을 제공한다. 이 기능에 대한 설정 방법은 JEUS Web Container 안내서”의 “4.3.5. 자동 Thread Pool 관리 설정(Thread 상태 통보)”을 참고한다.

  • EJB 리모트 요청 Thread

    EJB operation의 경우에는 다음의 시점에 interrupt status를 체크해서 javax.ejb.EJBException을 발생시킨다.

    • EJB 2.x 방식으로 create와 같은 EJBHome 메소드를 호출할 때(EJB 3.0의 경우 사용자가 EJB lookup을 하면 컨테이너 내부적으로 create 처리)

    • EJB 비즈니스 메소드를 호출할 때

    이때 발생하는 Exception에 대해서는 사용자 애플리케이션에서 적절하게 처리해 주어야 한다. 만약 EJB 비지니스 메소드 호출이 이미 들어간 상태에서 interrupt 시그널을 받았다면 Exception이 발생하지 않을 수 있다. 하지만 해당 메소드에서 다른 EJB를 호출한다던가, JDBC operation이나 JNDI operation을 사용하는 경우라면 interrupt가 걸릴 수도 있다.

  • JDBC

    JDBC operation의 경우에는 아래 operation을 수행하려고 할 때 interrupt 시그널을 받았다면 java.sql.SQLException이 발생한다. 이때 발생하는 Exception에 대해서는 사용자 애플리케이션에서 적절하게 처리해 주어야 한다.

    • DataSource#getConnection()을 통해 Connection Pool에서 커넥션을 가져올 때

    • Connection Pool에서 가져온 java.sql.Connection에 대해서 operation을 수행하려고 할 때

    • JDBC Connection Pool 설정에 use-sql-trace나 stmt-caching-size 옵션을 설정하고 executeQuery와 같은 operation을 수행 하려고 할 때(옵션에 대한 자세한 설명은 “8.3.4. Connection Pool 설정” 참고)

  • JNDI

    JNDI operation을 수행하는 중에도 interrupt의 효과가 있는 경우가 있다. 다음의 JNDI operation을 수행하려고 할 때 interrupt 시그널을 받았다면 javax.naming.NamingException이 발생한다. 이때 발생하는 Exception에 대해서는 사용자 애플리케이션에서 적절하게 처리해 주어야 한다.

    • JNDI 원격 커넥션을 맺을 때(javax.naming.InitialContext를 생성하는 시점)

    • JNDI operation을 하기 위해 원격 메시지를 보낼 때

      lookup, bind, rebind, rename과 같은 JNDI operation일 경우이다. 단, 로컬(같은 JVM)에 있는 레지스트리에 접근하거나 캐쉬에 접근하는 경우에는 interrupt의 효과가 없다.

  • IO 작업

    IO작업을 할 때는 항상은 아니지만 상황에 따라 interrupt의 효과가 있을 수 있다.

    • java.nio.channels.SocketChannel

      java.nio.channels.SocketChannel을 사용하는 경우에는 interrupt에 걸리게 된다. java.nio.channels.SocketChannel을 사용해서 연결할 때는 3단계로 분리된다.

      첫 번째 단계인 begin단계에서는 Thread에 interrupt status가 설정되었는지 체크하고 설정되어 있다면 채널을 종료한다. 실제 연결하는 단계에서는 interrupt status가 설정되어 있다면 connect()를 진행하지 않고, end 단계에서 interrupt가 걸려 있다면 java.nio.channels.ClosedByInterruptedException이 발생한다(이후에 interrupt status는 clear된다).

    • java.nio.channels.SocketChannel#read()/java.nio.channels.SocketChannel#write()

      java.nio.channels.SocketChannel#read()나 java.nio.channels.SocketChannel#write()하는 경우에도 역시 3단계로 나뉘게 된다.

      첫 번째 단계인 begin단계에서는 interrupt status가 설정되었는지 체크하고 설정되어 있다면 채널을 종료한다. 그리고 실제 IO를 처리하는 단계에서는 interrupt status가 설정되어 있다면 실제 read, write를 진행하지 않고, 마지막 end 단계에서는 java.nio.channels.ClosedByInterruptedException이 발생한다(이후에 interrupt status는 clear된다).

      java.nio.channels.ClosedByInterruptedException이 발생하고 난 후 이전에 만들었던 채널을 사용해서 read, write를 하려고 하면 IO 작업이 수행되지 않고 java.nio.channels.ClosedChannelException이 발생한다.

    • java.net.Socket 사용

      java.net.Socket을 사용할 때는 OS, JVM에 따라서 다르다. HP-UX와 Solaris에서는 JVM의 컴파일 옵션에 따라 Socket IO 작업에 interrupt를 걸 수 있다.

      Socket의 스트림을 통해 read나 write를 하려고 할 때 interrupt status가 체크되기 때문에 interrupt에 걸릴 수 있고 java.net.SocketException이 발생한다(이후에 interrupt status는 clear된다). 하지만 이때 실제 소켓이 끊어지는 것은 아니고 interrupt가 걸린 시점의 다음 operation만 중단된다(다음에 read, write operation을 수행하면 제대로 동작한다).

      그 외 Windows, IBM AIX, LINUX 등에서는 Socket 하는 Thread에 interrupt를 걸어도 효과가 없다.

  • Object#wait() / Thread#sleep() /Thread#join()

    Thread가 Object#wait(), Thread#sleep() 또는 Thread#join()하고 있는 상태라면 해당 Thread는 interrupt에 걸리게 된다. 이 경우 해당 Thread는 java.lang.InterruptedException이 발생한다(이후에 interrupt status는 clear된다).

참고

자세한 사항은 해당 클래스의 Javadoc API 문서를 참고한다.

JEUS에서는 콘솔 툴과 WebAdmin을 통해 Thread에 interrupt 시그널을 보낼 수 있는 명령을 제공한다.

다음은 JEUS 콘솔 툴을 사용하여 특정 Thread에 interrupt 시그널을 보내는 예제이다.

johan>interrupt-thread 79
WARNING: This function is EXPERIMENTAL yet and the status of target thread could b
e inconsistent.
Do you really want to signal the interruption hint to the thread [tid=79] in the e
ngine container [johan_container1]? (y : n):>y
Signaled the interruption hint

참고

JEUS 콘솔 툴의 interrupt-thread 명령에 대한 자세한 정보는 JEUS Reference Book”의 “4.2.3.29. interrupt-thread”를 WebAdmin을 통해 Thread에 interrupt를 거는 방법은 "JEUS WebAdmin 안내서"와 온라인 도움말을 참고한다.