본 장에서는 JEUS 웹 엔진에서 사용하는 스레드 풀의 구성 요소와 기본적인 설정 방법에 대해 설명한다.
웹 엔진에서 요청을 처리하기 위해서는 스레드 풀이 필수적이다. 이전 JEUS에서는 리스너와 커넥터 별로 있었던 스레드 풀이, JEUS 21부터는 3개의 레벨에서 스레드 풀을 설정하고 관리하고 있으며, 각 레벨은 WebContainer, VirtualHost, Context이다. 요청을 처리하기 위해서 어떤 스레드 풀을 선택할 것인지에 대한 우선순위가 존재하며, 기본적으로 Context --> VirtualHost --> WebContainer 순이다. Context와 VirtualHost 레벨에서의 스레드 풀은 선택사항이며, WebContainer 레벨의 스레드 풀은 항상 존재하는 풀이다.
WebContainer, VirtualHost, Context의 레벨의 스레드 풀 생성, 소멸 시점과 역할을 설명한다.
WebContainer 레벨의 스레드 풀은 웹 엔진이 기동될 때 생성되며, 조건에 맞는 Context와 VirtualHost의 스레드 풀이 없을 때 디폴트로 요청을 처리하는 스레드 풀이다. 웹 엔진이 종료될 때 스레드 풀이 소멸된다.
VirtualHost 레벨의 스레드 풀은 웹 엔진이 기동될 때 설정된 VirtualHost를 생성하거나 동적으로 VirtualHost를 추가할 때, 스레드 풀에 대한 설정이 존재하면 각 VirtualHost마다 스레드 풀을 생성한다. 참고로, System application을 위한 System Host와, 디폴트로 설정되는 Default Host는 스레드 풀을 생성하지 않는다. VirtualHost를 제거할 때 해당하는 스레드 풀이 소멸된다.
Context 레벨의 스레드 풀은 application이 deploy될 때 스레드 풀에 대한 설정이 존재하면 스레드 풀을 생성한다. Context 레벨의 스레드 풀은 다른 레벨의 스레드 풀과 달리 하나 이상의 스레드 풀을 설정할 수 있다. Context 레벨의 스레드 풀은 하나의 base 스레드 풀과 하나 이상의 Service Group 스레드 풀을 설정할 수 있다. Service Group 스레드 풀은 특정 uri로 온 요청들을 처리하기 위해 하나 이상의 uri를 ','로 구분하여 uri들을 설정할 수 있으며, 요청이 많이 들어올 리소스를 효율적으로 처리할 수 있도록 도와준다. uri에 매칭되는 Service Group 스레드 풀이 없을 경우에 base 스레드 풀이 설정되어 있다면, Service Group에 설정된 uri를 제외한 모든 요청들은 base 스레드 풀로 처리된다. 만약 base 스레드 풀도 설정되어 있지 않다면, VirtualHost 또는 디폴트인 WebContainer 레벨의 스레드 풀로 요청을 처리한다. application이 undeploy될 때 생성된 모든 스레드 풀이 소멸된다.
각 레벨의 스레드 풀 설정 방법을 설명한다.
WebContainer 레벨의 스레드 풀은 domain.xml에 정의되어야 한다. 만약 설정하지 않는다면, JEUS 기동에 실패하게 된다.
[예 4.1] WebContainer 레벨의 스레드 풀 : <<domain.xml>>
<web-engine> <thread-pool> <min>10</min> <max>40</max> <max-idle-time>300000</max-idle-time> <max-queue>30</max-queue> </thread-pool> </web-engin>
위의 예제에 나온 것 같이 WebContainer 레벨의 스레드 풀은 <web-engine> 하위에
하나의 스레드 풀을 설정할 수 있다. 선택된 Context와 VirtualHost 레벨의 스레드 풀이 없을 경우에 요청을
처리한다.
VirtualHost 레벨의 스레드 풀은 domain.xml에 정의되어야 한다. 선택적으로 설정할 수 있으며, 설정하지 않을 경우에는 WebContainer 레벨의 스레드 풀에서 처리된다.
[예 4.2] VirtualHost 레벨의 스레드 풀 : <<domain.xml>>
<web-engine> <virtual-host> <virtual-host-name>testHost</virtual-host-name> <host-name>192.1.1.1</host-name> <thread-pool> <min>10</min> <max>20</max> <max-idle-time>300000</max-idle-time> <max-queue>30</max-queue> </thread-pool> </virtual-host> </web-engin>
위의 예제에 나온 것 같이 VirtualHost 레벨의 스레드 풀은 <virtual-host> 하위에
하나의 스레드 풀을 설정할 수 있다. 선택된 Context 레벨의 스레드 풀이 없을 경우에 요청을 처리하고, VirtualHost
레벨의 스레드 풀을 설정하지 않으면 WebContainer 레벨의 스레드 풀로 넘긴다.
Context 레벨의 스레드 풀은 jeus-web-dd.xml에 정의되어야 한다. 선택적으로 설정할 수 있으며, 설정하지 않을 경우에는 VirtualHost 레벨의 스레드 풀에서 처리된다.
[예 4.3] Context 레벨의 스레드 풀 : <<jeus-web-dd.xml>>
<jeus-web-dd> <thread-pool> <base> <name>baseThreadPool</name> <min>30</min> <max>50</max> <max-idle-time>300000</max-idle-time> <max-queue>30</max-queue> </base> <service-group> <name>service1</name> <uri>/index.html,/index.jsp</uri> <min>10</min> <max>20</max> <max-idle-time>300000</max-idle-time> <max-queue>30</max-queue> </service-group> <service-group> <name>service2</name> <uri>/mostRequestedResource</uri> <min>10</min> <max>20</max> <max-idle-time>300000</max-idle-time> <max-queue>30</max-queue> </service-group> </thread-pool> </jeus-web-dd>
위의 예제에 나온 것 같이 Context 레벨의 스레드 풀은 <jeus-web-dd> 하위에 하나의
base 스레드 풀과 하나 이상의 service-group 스레드 풀을 설정할 수 있다. 다수의 Context 스레드 풀을 구분하기
위해서 unique한 name을 지정해주어야 한다. 요청된 uri가 service-group에 설정된 uri와 매칭된다면 해당
service-group의 스레드풀로 요청을 처리하고, 없을 경우에는 base 스레드 풀로 처리한다. base 스레드 풀이 설정되지
않았다면, VirtualHost 레벨의 스레드 풀로 넘긴다.
Worker Thread Pool에 대한 설정이다.
다음은 세부 사항을 설정하는 하위 항목에 대한 설명이다.
항목 | 설명 |
---|---|
Min | Pool에서 관리할 최소 Worker Thread의 개수이다. |
Max | Pool에서 관리할 최대 Worker Thread의 개수이다. |
Maximum Idle Time | Pool 내에 존재하던 Thread가 제거되기 전까지의 사용되고 있지 않은 시간을 지정한다. |
Max Queue | Queue에 대기할 수 있는 요청의 최대 개수를 설정한다. |
Thread State Notify | 블록되는 Worker Thread가 발생될 경우 이를 알려준다. 각 Thread Pool은 장애가 발생했을 때 취하는 액션을 정의하는 'Thread State Notify' 항목을 가지고 있다. 이것에 대해서는 “4.4. 자동 Thread Pool 관리 설정(Thread 상태 통보)”을 참고한다. |
Thread 상태 통보는 이메일 통지나 서버 재시작 권고를 위해 필요한 최소의 Worker Thread 수와 관련된 오류 조건을 정의한다. 리스너 및 커넥터 설정 화면의 Thread State Notify 영역에서 설정한다.
자동 Thread Pool 관리 설정이 되면 'Max Thread Active Time' 설정값을 기준으로 Worker Thread가 관리된다. 요청을 받아 처리를 시작한 시점부터 Max Thread Active 설정 시간을 초과한 Thread들은 Blocked Thread로 관리가 된다. 그리고 Blocked Thread가 아닌 일반 Thread들의 숫자가 Thread Pool에서 설정한 최솟값보다 작을 경우는 새로운 Worker Thread를 생성하여 최솟값을 유지할 수 있게 한다.
Thread Pool의 Thread 상태 변경에 대한 통보 설정을 통해 원하는 통보를 받을 수 있다.
다음은 이메일 알림자를 포함하고 있는 설정 예이다. 이메일 알림자를 통해 받을 이메일의 설정은 “JEUS Server 안내서”의 “8.3. 로깅 설정”에서 "SMTP 핸들러 설정"을 참고한다.
다음과 각 항목에 대한 설명이다.
항목 | 설명 |
---|---|
Max Thread Active Time | 블록되기 전까지 Worker Thread가 사용될 수 있는 최대시간을 설정한다. 이 시간은 Worker Thread가 클라이언트 요청을 서비스할 때부터 측정된다(서블릿이 수행될 때). 설정한 시간이 초과되었거나 또는 Thread가 자유롭게 되어 Thread Pool로 되돌아 갈 때 만료된다(Thread가 block되지 않는 상황). 설정값이 0이거나 음수이면 무시된다. |
Notify Threshold Ratio | 존재할 수 있는 Blocked Thread의 최대 비율을 설정한다. 전체 Thread 개수 대비 Blocked Thread의 비율이 초과되면, 오류 조건으로 결정되어 이메일 알림자를 통하여 이메일 통보가 전송된다. 1보다 작은 소숫점으로 설정하며, 0이거나 음수이면 무시된다. |
Restart Threshold Ratio | 존재할 수 있는 Blocked Thread의 최대 비율을 설정한다. 전체 Thread 개수 대비 Blocked Thread의 비율이 초과되면, 오류 조건으로 결정되어 이메일 알림자를 통하여 이메일 통보가 전송된다. 그 후에 서버 로그에 서버 재시작 권고 메시지가 기록된다. 1보다 작은 소숫점으로 설정하며, 0이거나 음수이면 이 설정이 무시된다. |
Notify Subject | 경고 이메일을 전송할 때 사용된다. |
Restart Subject | 엔진 로그 및 통보할 때 사용하는 이메일에 사용된다. |
Interrupt Thread | Active Timeout이 발생할 때, 즉 Worker Thread가 'Max Thread Active Time' 설정값 이상으로 요청을 처리 중일 때 해당 Thread의 interrupt 발생 유무를 결정한다.
|
Active Timeout Notification | Active Timeout 발생이 이메일 전송 여부를 결정한다.
|
스레드 풀을 구성할 때 적용되는 규칙은 다음과 같다.
Context, VirtualHost 레벨의 스레드 풀을 사용하기 위해서는 스레드 풀로 작업을 넘기기 전에 요청을 읽고 Context와 Host를 판단할 수 있어야 한다.
Http, Ajp13, Tcp 리스너에서만 사용 가능하며, WebtoB Connector에서는 오직 WebContainer 스레드 풀만 사용한다.
WebtoB Connector는 이전과 달리 Connection과 스레드가 1대 1 매칭되어 있는 형태가 아니고 별개의 것으로 구분되어 있다.
Service Group 스레드 풀을 설정할 때 똑같은 uri를 서로 다른 Service Group에 정의하지 않도록 주의해야한다.
uri는 '/'로 시작해야 하며, 서블릿 표준에서 Context path 다음으로 오는 Servlet path와 path Info에 해당한다.
uri를 정의할 때는 하위의 경로도 포함할 수 있다는 것을 고려해야 한다.
예를 들어, Service Group의 uri에 "/myServlet/"으로 지정하였다면, /testContext/myServlet/servlet1과 /testContext/myServlet/servlet2 요청 모두 "/myServlet/"으로 설정한 Service Group으로 처리한다.
다수의 Service Group이 정의되어 있을 때는 가장 많이 매칭되는 uri를 선택하도록 한다.
예를 들어, Service Group1의 uri에 "/myServlet/"으로 지정하였고, Service Group2의 uri에 "/myServlet/servlet2"으로 지정하였다면, /testContext/myServlet/servlet1 요청은 Service Group1로 /testContext/myServlet/servlet2 요청은 Service Group2로 처리한다.