Managed Objects
본 장에서는 Jakarta Concurrency에서 제공하는 Managed Objects에 대해서 간략하게 설명하고 사용 예제를 기술한다.
1. ManagedExecutorService
javax.enterprise.concurrent.ManagedExecutorService 인터페이스는 Java SE의 java.util.concurrent.ExecutorService 인터페이스를 상속한다. ExecutorService와 동일하게 비동기 작업을 수행하기 위해 이용되고, 애플리케이션 서버는 비동기로 실행되는 작업의 컨텍스트 정보를 유지시켜준다.
리소스 정의 예제
다음은 ManagedExecutorService를 리소스로 정의한 예제이다.
<domain> ... <server> <data-sources> <data-source>testdb</data-source> </data-sources> <managed-executor-service>mes1</managed-executor-service> </server> <resources> <managed-executor-service> <export-name>mes1</export-name> <long-running-task>true</long-running-task> <thread-pool> <min>10</min> <max>20</max> <keep-alive-time>60000</keep-alive-time> <queue-size>4096</queue-size> <stuck-thread-handling> <max-stuck-thread-time>3600000</max-stuck-thread-time> <action-on-stuck-thread>None</action-on-stuck-thread> <stuck-thread-check-period>300000</stuck-thread-check-period> </stuck-thread-handling> </thread-pool> </managed-executor-service> </resources> ... </domain>
애플리케이션 예제
다음은 ManagedExecutorService를 활용한 애플리케이션 예제이다.
public class AppServlet extends HTTPServlet implements Servlet { // Retrieve our executor instance. @Resource(name=mes1”) ManagedExecutorService mes; protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ArrayList<Callable> builderTasks = new ArrayList<Callable>(); builderTasks.add(new AccountTask(reqID, accountID)); builderTasks.add(new InsuranceTask(reqID, accountID)); // Submit the tasks and wait. List<Future<Object>> results = mes.invokeAll(builderTasks); AccountInfo accountInfo = (AccountInfo) results.get(0).get(); InsuranceInfo insInfo = (InsuranceInfo) results.get(1).get(); // Process the results } }
WebAdmin 예제
WebAdmin에서는 다음과 같은 과정을 통해 ManagedExecutorService 설정을 수행할 수 있다.
-
Webadmin 메인 화면에서 마스터 서버를 선택하여 설정 화면을 펼친다.
-
설정 화면 상단 탭에서 '리소스' 항목을 선택한 후 'Concurrency Utilities' 항목을 클릭하면 Concurrency Utilities에 대한 기본 설정 페이지가 나타난다.
-
Concurrency Utilities 기본 설정 페이지 상단 탭에서 'Managed Executor Service'를 선택한다.
-
[Managed Executor Service] 탭 화면에서 Managed Executor Service에 대한 생성, 삭제 등 설정 작업을 수행할 수 있다.
설정 항목에 대한 설명은 다음과 같다.
-
기본 항목
항목 설명 Export Name
Managed Executor Service를 JNDI Naming Server에 등록할 때 사용할 이름을 설정한다.
Long Running Task
Managed Executor Service가 오래 수행하는 작업인지 여부를 표시한다.
-
Thread Pool
Managed Executor Service에서 사용하는 Thread Pool 설정을 나타낸다.
항목 설명 Min
Thread Pool에서 관리하는 스레드 수의 최솟값이다.
Max
Thread Pool에서 관리하는 스레드 수의 최댓값이다.
Keep Alive Time
설정한 시간 동안 사용하지 않은 Min 이하의 스레드를 자동적으로 Thread Pool에서 제거한다. 0으로 설정하는 경우 제거하지 않는다.
Queue Size
Thread Pool이 처리할 업무 개체를 저장하는 queue의 크기를 지정한다.
-
Stuck Thread Handling
스레드가 특정 업무 때문에 일정 시간 계속 점유된 상태일 경우 해당 스레드에 대해 특정한 동작을 취하기 위한 설정이다.
항목 설명 Max Stuck Thread Time
스레드를 Stuck Thread로 판단하는 기준이 되는 값을 설정한다. 설정된 시간 이상 계속 점유된 상태이면 해당 스레드를 Stuck Thread로 간주한다.
Action On Stuck Thread
Stuck Thread로 판단된 경우 그 스레드에 대해 특정 액션을 취하기 위한 설정이다.
Stuck Thread Check Period
Stuck Thread의 상태를 체크하는 주기를 설정한다.
User Warning Class
action-on-stuck-thread를 Warning으로 설정된 경우에 default는 thread dump를 찍어주도록 되어있으나, 사용자가 원하는 작업을 할 수 있도록 직접 클래스를 작성할 경우 이 설정을 사용한다. 해당 클래스는 jeus.util.pool.Warning을 반드시 implement해야 하며, jeus.util.pool.Warning interface는 jclient.jar에서 찾을 수 있다. 클래스를 작성한 후에 사용할 대상 서버의 SERVER_HOME/lib/application에 위치시킨다.
-
2. ManagedScheduledExecutorService
javax.enterprise.concurrent.ManagedExecutorService 인터페이스는 ManagedExecutorService의 모든 기능을 상속받는 동시에 Java SE의 java.util.concurrent.ScheduledExecutorService의 기능을 상속받아 작업의 지연 실행이나 주기적 실행이 가능하도록 기능을 제공한다. 추가적으로 Trigger와 ManagedTaskListener 인터페이스를 통해 작업의 실행을 제어할 수 있도록 한다.
리소스 정의 예제
다음은 ManagedScheduledExecutorService를 리소스로 정의한 예제이다.
<domain> ... <server> <data-sources> <data-source>testdb</data-source> </data-sources> <managed-scheduled-executor-service>mses1</managed-scheduled-executor-service> </server> <resources> <managed-scheduled-executor-service> <export-name>mses1</export-name> <long-running-task>true</long-running-task> <thread-pool> <min>10</min> <max>20</max> <keep-alive-time>60000</keep-alive-time> <queue-size>4096</queue-size> <stuck-thread-handling> <max-stuck-thread-time>3600000</max-stuck-thread-time> <action-on-stuck-thread>None</action-on-stuck-thread> <stuck-thread-check-period>300000</stuck-thread-check-period> </stuck-thread-handling> </thread-pool> </managed-scheduled-executor-service> </resources> ... </domain>
애플리케이션 예제
다음은 ManagedScheduledExecutorService를 활용한 애플리케이션 예제이다.
public class AppServlet extends HTTPServlet implements Servlet { @Resource(name=mses1”) ManagedScheduledExecutorService mses; protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Runnable printTask = new Runnable() { @Override public void run() { System.out.println(System.currentTimeMillis()); } }; // printTask가 5초마다 주기적으로 실행됨 mses.schedule(printTask, 5, TimeUnit.SECONDS); } }
WebAdmin 예제
Webadmin에서는 다음과 같은 과정을 통해 Managed Scheduled Executor Service에 대한 설정을 수행할 수 있다.
-
Webadmin 메인 화면에서 마스터 서버를 선택하여 설정 화면을 펼친다.
-
설정 화면 상단 탭에서 '리소스' 항목을 선택한 후 'Concurrency Utilities' 항목을 클릭하면 Concurrency Utilities에 대한 기본 설정 페이지가 나타난다.
-
Concurrency Utilities 기본 설정 페이지 상단 탭에서 'Managed Scheduled Executor Service'를 선택한다.
-
[Managed Scheduled Executor Service] 탭 화면에서 Managed Scheduled Executor Service에 대한 생성, 삭제 등 설정 작업을 수행할 수 있다.
설정 항목에 대한 설명은 다음과 같다.
-
기본 항목
항목 설명 Export Name
managed-scheduled-executor-service가 Naming Server에 등록되는 이름을 설정한다.
Long Running Task
managed-scheduled-executor-service에서 동작하는 task가 오래 수행하는 지의 여부이며 boolean의 값으로 나타낸다.
-
Thread Pool
Managed Executor Service에서 사용하는 Thread Pool 설정을 나타낸다.
항목 설명 Min
Thread Pool에서 관리하는 스레드 수의 최솟값이다.
Max
Thread Pool에서 관리하는 스레드 수의 최댓값이다.
Keep Alive Time
Min 이하의 스레드에 대해서 설정된 시간 동안 사용되지 않는다면 자동적으로 Thread Pool에서 제거된다. 0이면 제거하지 않는다.
Queue Size
Thread Pool이 처리할 업무 개체를 저장하는 queue의 크기를 지정한다.
-
Stuck Thread Handling
스레드가 특정 업무 때문에 일정 시간 계속 점유된 상태일 경우 해당 스레드에 대해 특정한 동작을 취하기 위한 설정이다.
항목 설명 Max Stuck Thread Time
스레드를 Stuck Thread로 판단하는 기준이 되는 값을 설정한다. 설정된 시간 이상 계속 점유된 상태이면 해당 스레드를 Stuck Thread로 간주한다.
Action On Stuck Thread
Stuck Thread로 판단된 경우 그 스레드에 대해 특정 액션을 취하기 위한 설정이다.
Stuck Thread Check Period
Stuck Thread의 상태를 체크하는 주기를 설정한다.
User Warning Class
action-on-stuck-thread를 Warning으로 설정된 경우에 default는 thread dump를 찍어주도록 되어있으나, 사용자가 원하는 작업을 할 수 있도록 직접 클래스를 작성할 경우 이 설정을 사용한다. 해당 클래스는 jeus.util.pool.Warning을 반드시 implement해야 하며, jeus.util.pool.Warning interface는 jclient.jar에서 찾을 수 있다. 클래스를 작성한 후에 사용할 대상 서버의 SERVER_HOME/lib/application에 위치시킨다.
-
3. ContextService
ExecutorService를 이용하지 않고 ContextService를 통해 Managed Task를 생성하는 방식을 제공한다. 본 기능을 이용하여 사용자는 태스크를 만들 때 컨텍스트에 대해서 신경쓰지 않아도 애플리케이션 서버 내부적으로 작업이 실행될 때 컨텍스트를 유지시켜준다. 좀더 상세하게는 Dynamic Proxy를 이용해서 현재 작업을 실행하기 전에 해당 스레드에 컨텍스트를 설정하고 작업을 수행한다. 모든 작업이 완료되면 컨텍스트를 복귀하는 작업을 대신 수행한다.
리소스 정의 예제
다음은 ContextService를 리소스로 정의한 예제이다.
<domain> ... <server> <data-sources> <data-source>testdb</data-source> </data-sources> <context-service>cs1</context-service> </server> <resources> <context-service> <export-name>cs1</export-name> </context-service> </resources> ... </domain>
애플리케이션 예제
다음은 ContextService를 활용한 애플리케이션 예제이다.
public class AppServlet extends HTTPServlet implements Servlet { @Resource(name=cs1”) ContextService cs; protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 일반적인 Runnable task Runnable simpleTask = new Runnable() { @Override public void run() { int sum = 0; for (int i = 0; i < 10; i++) { sum += i; } System.out.println(sum); } }; // 일반 task를 ContextService를 통해서 Contextual task로 만듦 cs.createContextualProxy(simpleTask, Runnable.class); // SE에서 제공하는 Executor에 Contextual task를 넘김 ExecutorService es = Executors.newFixedThreadPool(1); es.submit(simpleTask); } }
WebAdmin 예제
Context Service에 대한 설정 방법 및 각 설정 항목에 대한 설명은 다음과 같다.
-
Webadmin 메인 화면에서 마스터 서버를 선택하여 설정 화면을 펼친다.
-
설정 화면 상단 탭에서 '리소스' 항목을 선택한 후 'Concurrency Utilities' 항목을 클릭하면 Concurrency Utilities에 대한 기본 설정 페이지가 나타난다.
-
Concurrency Utilities 기본 설정 페이지 상단 탭에서 'Context Service'를 선택한다.
-
[Context Service] 탭 화면에서 Context Service에 대한 생성, 삭제 등 설정 작업을 수행할 수 있다.
설정 항목에 대한 설명은 다음과 같다.
-
기본 항목
항목 설명 Export Name
context-service가 Naming Server에 등록되는 이름을 설정한다.
-
4. ManagedThreadFactory
javax.enterprise.concurrent.ManagedThreadFactory 인터페이스는 Java SE의 java.util.concurrent.ThreadFactory 기능을 상속받아 스레드를 생성하는 기능을 제공한다. 일반적으로 ThreadFactory는 ThreadPoolExecutor를 생성할 때 생성자의 파라미터로 넘기는 곳에 사용한다. 따라서, Java SE의 Concurrency API 상에서도 worker 스레드가 작업을 실행할 때 Task에 대한 컨텍스트를 유지해줄 수 있다.
리소스 정의 예제
다음은 ManagedThreadFactory를 리소스로 정의한 예제이다.
<domain> ... <server> <data-sources> <data-source>testdb</data-source> </data-sources> <managed-thread-factory>mtf1</managed-thread-factory> </server> <resources> <managed-thread-factory> <export-name>mtf1</export-name> <thread-priority>5</thread-priority> </managed-thread-factory> </resources> ... </domain>
애플리케이션 예제
다음은 ManagedThreadFactory를 활용한 애플리케이션 예제이다.
public class AppServlet extends HTTPServlet implements Servlet { // Retrieve our executor instance. @Resource(name=mtf1”) ManagedThreadFactory mtf; protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 일반적인 Runnable task Runnable simpleTask = new Runnable() { @Override public void run() { int sum = 0; for (int i = 0; i < 10; i++) { sum += i; } System.out.println(sum); } }; // simpleTask를 ManagedThreadFactory에서 제공되는 thread에서 실행 mtf.newThread(simpleTask).start(); // 혹은 ThreadPoolExecutor의 매개변수로 ThreadFactory를 전달 Executor e = new ThreadPoolExecutor(5, 10, 6L, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(4096), mtf); e.execute(new SimpleTask()); } }
WebAdmin 예제
Managed Thread Factory에 대한 설정 방법 및 각 설정 항목에 대한 설명은 다음과 같다.
-
Webadmin 메인 화면에서 마스터 서버를 선택하여 설정 화면을 펼친다.
-
설정 화면 상단 탭에서 '리소스' 항목을 선택한 후 'Concurrency Utilities' 항목을 클릭하면 Concurrency Utilities에 대한 기본 설정 페이지가 나타난다.
-
Concurrency Utilities 기본 설정 페이지 상단 탭에서 'Managed Thread Factory'를 선택한다.
-
[Managed Thread Factory] 탭 화면에서 Managed Thread Factory에 대한 생성, 삭제 등 설정 작업을 수행할 수 있다.
설정 항목에 대한 설명은 다음과 같다.
-
기본 항목
항목 설명 Export Name
managed-thread-factory가 Naming Server에 등록되는 이름을 설정한다.
Thread Priority
thread의 priority를 나타낸다. (기본값: 5)
-