동시성 및 비동기 프로그래밍 모델을 사용하는 애플리케이션을 Liberty로 마이그레이션
Concurrency Utilities for Java™ EE, 비동기 Bean 및 CommonJ 타이머와 작업 관리자를 사용하는 애플리케이션을 WebSphere® Application Server Traditional에서 WebSphere Application Server Liberty로 마이그레이션할 수 있습니다.
비동기 Bean, CommonJ 타이머 및 작업 관리자는 Liberty에서 사용될 수 없습니다. Liberty로 마이그레이션하는 경우에는 애플리케이션이 Concurrency Utilities for Java EE 프로그래밍 모델로 전환해야 합니다. 추가 정보는 Concurrency Utilities for Java EE를 구현하는 API 태스크 예의 내용을 참조하십시오.
구성 및 스레딩의 차이점
WebSphere Application Server Traditional은 Liberty에서 다르게 구성되거나 사용할 수 없는 스레드 풀링과 관련된 Java EE에 대해 여러 구성 옵션을 제공합니다. Liberty에는 Liberty 컴포넌트에서도 공유하는 모든 관리되는 실행기 및 관리되는 예약 실행기 간에 단일 공통 스레드 풀이 있습니다. 이를 통해 Liberty는 스레드 관리를 최적화합니다. WebSphere Application Server Traditional에서 각 작업 관리자는 두 개의 스레드 풀로 구성될 수 있습니다. 한 스레드 풀은 가능한 빨리 실행하도록 제출되고(관리되는 실행기의 submit/execute/invoke 메소드) 구성 가능한 작업 요청 큐와 큐 용량이 초과될 때 취할 조치를 갖는 태스크를 위한 것입니다. 다른 스레드 풀은 스케줄된 태스크(관리되는 예약 실행기의 schedule 메소드)를 위한 것입니다.
Liberty의 개별 스레드 풀에서 Concurrency Utilities for Java EE를 사용하려는 경우, WebSphere Application Server Traditional에서 사용할 수 있는 구성 옵션과 유사한 동작을 얻기 위해 다양한 접근 방식을 취할 수 있습니다.
![[17.0.0.4 and later]](../ng_v17004plus.gif)
동시성 정책 구성 사용
concurrencyPolicy 요소를 사용하여 Liberty에서 WebSphere Application Server Traditional의 일부 동작을 복제합니다. 다음 표는 concurrencyPolicy 요소에 사용 가능한 구성 옵션과 이 요소를 WebSphere Application Server Traditional과 비교하는 방법을 나열합니다. concurrencyPolicy 구성은 스케줄된 태스크에 적용되지 않습니다.
Liberty 관리 실행기 concurrencyPolicy | WebSphere Application Server Traditional 작업 관리자 및 관리 실행기 |
---|---|
max | 최대 스레드 |
maxQueueSize | 작업 요청 큐 크기 |
maxWaitForEnqueue | 작업 요청 큐 전체 조치 = 대기 |
runIfQueueFull = false | 작업 요청 큐 전체 조치 = 실패 |
startTimeout | 시작 제한시간 |
longRunningPolicyRef + longrunning hint | 디먼 작업 |
신속(expedite) 요소는 고정된 수의 최소 스레드 대신 Liberty 글로벌 스레드 풀에서 신속하게 처리되는 스레드의 대상 최소값과 동일합니다.
관리되는 스레드 팩토리 주위에 Java SE 생성기 구성
Java SE의 java.util.concurrent 패키지는 특정 스레드 팩토리 주위에 스레드 풀을 실행기 및 예약 실행기로 구성하는 여러 가지 방법을 제공합니다. 관리되는 스레드 팩토리는 관리되지 않은 스레드 팩토리 위치에 제공되어 관리되는 스레드에 대해 태스크를 실행하는 스레드 풀을 생성할 수 있습니다. 관리되는 실행기 및 관리되는 예약 실행기와는 달리, 이들 실행기에 의해 풀링되는 관리되는 스레드는 태스크가 제출 또는 스케줄되었을 때가 아니라 관리되는 스레드 팩토리가 검색되었을 때의 스레드 컨텍스트와 함께 실행됩니다. 스레드 컨텍스트는 또한 스레드 수명 동안 관리되는 스레드에 남아 있어서 스레드 컨텍스트 스위칭 오버헤드를 줄입니다.
![[17.0.0.4 and later]](../ng_v17004plus.gif)
최대 작업 스레드 및 작업 큐 구성의 대체 예
<managedExecutorService jndiName="concurrent/execSvc">
<concurrencyPolicy max="2" maxQueueSize="3" runIfQueueFull="false" maxWaitForEnqueue="0"/>
</managedExecutorService>
최대 알람 스레드의 대체 예
int maxAlarms = 2;
ManagedThreadFactory threadFactory =
(ManagedThreadFactory) new InitialContext().lookup(
"java:comp/DefaultManagedThreadFactory");
ScheduledExecutorService executor =
Executors.newScheduledThreadPool(maxAlarms, threadFactory);
Callable<Integer> task = new MyTask();
ScheduledFuture<Integer> future = executor.schedule(
task, 50, TimeUnit.SECONDS);
int result = future.get();
![[17.0.0.4 and later]](../ng_v17004plus.gif)
시작 제한시간 적용
<managedExecutorService jndiName="concurrent/execSvc">
<concurrencyPolicy startTimeout="1m"/>
</managedExecutorService>
작업 제한시간 적용
WebSphere Application Server Traditional을 사용하여 가능한 한 빨리 실행하기 위해 제출되는 태스크에 적용되는 작업 제한시간을 구성합니다(submit/execute/invoke 메소드). 태스크가 할당된 작업 제한시간보다 오래 실행되는 경우 프로그램에서는 이를 인터럽트하여 태스크를 취소하려고 합니다. Liberty는 작업 제한시간을 구성 옵션으로 가지고 있지 않지만 관리 태스크 리스너로 태스크를 제출하여 유사한 동작을 구현할 수 있습니다. taskStarting 알림에 대한 응답에서 관리 태스크 리스너는 Future 메소드를 취소하도록 태스크를 스케줄합니다. 또는 관리 태스크 리스너를 사용할 수 없는 스레드 풀 실행기를 사용하는 경우 스레드 풀 실행기 beforeExecute 메소드를 대체하여 실행 스레드를 인터럽트하는 태스크를 스케줄할 수 있습니다.
작업 제한시간의 대체 예
ManagedExecutorService executor =
(ManagedExecutorService) new InitialContext().lookup(
"java:comp/DefaultManagedExecutorService");
Callable<Long> slowTask = new SlowTask();
slowTask = ManagedExecutors.managedTask(
slowTask, new WorkTimeout(5, TimeUnit.SECONDS));
Future<Long> future = executor.submit(slowTask);
try {
long result = future.get(1, TimeUnit.MINUTES);
// task successful...
} catch (CancellationException x) {
// task was canceled, possibly due to timeout
}
public class WorkTimeout implements ManagedTaskListener {
private final long timeout;
private final TimeUnit unit;
public WorkTimeout(long timeout, TimeUnit unit) {
this.timeout = timeout;
this.unit = unit;
}
public void taskSubmitted(Future<?> future,
ManagedExecutorService executor, Object task) {}
public void taskStarting(final Future<?> future,
ManagedExecutorService executor, Object task) {
try {
ScheduledExecutorService scheduledExecutor =
(ScheduledExecutorService) new InitialContext().lookup(
"java:comp/DefaultManagedScheduledExecutorService");
scheduledExecutor.schedule(new Runnable() {
@Override
public void run() {
if (!future.isDone())
future.cancel(true);
}
}, timeout, unit);
} catch (NamingException x) {
x.printStackTrace(System.out);
}
}
public void taskAborted(Future<?> future, ManagedExecutorService executor, Object task, Throwable x) {}
public void taskDone(Future<?> future, ManagedExecutorService executor, Object task, Throwable x) {}
}
![[17.0.0.4 and later]](../ng_v17004plus.gif)
디먼 작업의 예
Configuration:
<concurrencyPolicy id="longRunning" max="2"/>
<managedExecutorService jndiName="concurrent/execSvc" longRunningPolicyRef="longRunning" />
Application code:
ManagedExecutorService executor =
(ManagedExecutorService) new InitialContext().lookup(
"concurrent/execSvc");
Map<String, String> props = Collections.singletonMap(ManagedTask.LONGRUNNING_HINT,
Boolean.TRUE.toString());
Callable<Long> slowTask = ManagedExecutors.managedTask(new SlowTask(), props, null);
Future<Long> future = executor.submit(slowTask);