2.8. 스레드 모델

2.8.1. Java 스레드 풀 API

Apache Camel 스레딩 모델은 Sun의 JDK 1.5에서 먼저 사용 가능하게 된 강력한 Java 동시성 API인 Package java.util.concurrent 를 기반으로 합니다. 이 API의 주요 인터페이스는 스레드 풀을 나타내는 ExecutorService 인터페이스입니다. 동시성 API를 사용하면 다양한 시나리오를 대상으로 다양한 종류의 스레드 풀을 생성할 수 있습니다.

2.8.2. Apache Camel 스레드 풀 API

Apache Camel 스레드 풀 API는 Apache Camel 애플리케이션의 모든 스레드 풀에 대해 중앙 팩토리( org.apache.camel.spi.ExecutorServiceManager 유형)를 제공하여 Java 동시성 API를 기반으로 빌드됩니다. 이러한 방식으로 스레드 풀 생성을 중앙 집중화하면 다음과 같은 몇 가지 이점이 있습니다.

  • 유틸리티 클래스를 사용하여 스레드 풀 생성 간소화.
  • 스레드 풀을 정상 종료와 통합.
  • 로깅 및 관리에 유용한 정보를 제공하는 스레드가 자동으로 제공됩니다.

2.8.3. 구성 요소 스레딩 모델

일부 Apache Camel 구성 요소는 SEDA, JMS 및 Cryostatty Cryostat-의 경우 본질적으로 다중 스레드로 분류됩니다. 이러한 구성 요소는 모두 Apache Camel 스레딩 모델 및 스레드 풀 API를 사용하여 구현되었습니다.

자체 Apache Camel 구성 요소를 구현하려는 경우 스레드 코드를 Apache Camel 스레딩 모델과 통합하는 것이 좋습니다. 예를 들어 구성 요소에 스레드 풀이 필요한 경우 CamelContext의 ExecutorServiceManager 오브젝트를 사용하여 생성하는 것이 좋습니다.

2.8.4. 프로세서 스레딩 모델

Apache Camel의 표준 프로세서 중 일부는 기본적으로 자체 스레드 풀을 생성합니다. 이러한 스레딩 인식 프로세서는 Apache Camel 스레딩 모델과 통합되며 사용하는 스레드 풀을 사용자 지정할 수 있는 다양한 옵션을 제공합니다.

표 2.8. “프로세서 스레드 옵션” Apache Camel에 내장된 스레드 인식 프로세서에서 스레드 풀을 제어하고 설정하는 다양한 옵션을 보여줍니다.

표 2.8. 프로세서 스레드 옵션

프로세서Java DSLXML DSL

aggregate

parallelProcessing()
executorService()
executorServiceRef()
@parallelProcessing
@executorServiceRef

멀티 캐스트

parallelProcessing()
executorService()
executorServiceRef()
@parallelProcessing
@executorServiceRef

recipientList

parallelProcessing()
executorService()
executorServiceRef()
@parallelProcessing
@executorServiceRef

분할

parallelProcessing()
executorService()
executorServiceRef()
@parallelProcessing
@executorServiceRef

스레드

executorService()
executorServiceRef()
poolSize()
maxPoolSize()
keepAliveTime()
timeUnit()
maxQueueSize()
rejectedPolicy()
@executorServiceRef
@poolSize
@maxPoolSize
@keepAliveTime
@timeUnit
@maxQueueSize
@rejectedPolicy

wireTap

wireTap(String uri, ExecutorService executorService)
wireTap(String uri, String executorServiceRef)
@executorServiceRef

2.8.5. 스레드 DSL 옵션

스레드 프로세서는 스레드 풀을 경로에 도입하는 데 사용할 수 있는 범용 DSL 명령입니다. 스레드 풀을 사용자 지정하는 다음 옵션을 지원합니다.

poolSize()
풀에 있는 최소 스레드 수(및 초기 풀 크기).
maxPoolSize()
풀의 최대 스레드 수입니다.
keepAliveTime()
이 기간(초 단위로 지정)보다 오래 유휴 상태인 스레드가 있는 경우 종료됩니다.
timeUnit()
java.util.concurrent.TimeUnit 유형을 사용하여 지정된 시간 단위는 활성 상태를 유지합니다.
maxQueueSize()
이 스레드 풀이 들어오는 작업 큐에 저장할 수 있는 최대 보류 중인 작업 수입니다.
rejectedPolicy()
들어오는 작업 큐가 가득 차면 수행할 작업을 지정합니다. 참조 표 2.10. “스레드 풀 빌더 옵션”
참고

이전 스레드 풀 옵션은 executorServiceRef 옵션과 호환되지 않습니다 (예: 이러한 옵션을 사용하여 executorServiceRef 옵션에서 참조하는 스레드 풀의 설정을 재정의할 수 없습니다). Apache Camel은 이를 적용하기 위해 DSL을 검증합니다.

2.8.6. 기본 스레드 풀 생성

스레드 인식 프로세서 중 하나에 대한 기본 스레드 풀을 생성하려면 XML DSL에서 parallelProcessing () 하위 복제 또는 병렬Processing 특성을 사용하여 parallelProcessing 옵션을 활성화합니다.

예를 들어 Java DSL에서는 다음과 같이 기본 스레드 풀(스레드 풀이 동시에 멀티 캐스트 대상을 처리하는 데 사용되는) 멀티캐스트 프로세서를 호출할 수 있습니다.

from("direct:start")
  .multicast().parallelProcessing()
    .to("mock:first")
    .to("mock:second")
    .to("mock:third");

다음과 같이 XML DSL에서 동일한 경로를 정의할 수 있습니다.

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="direct:start"/>
        <multicast parallelProcessing="true">
            <to uri="mock:first"/>
            <to uri="mock:second"/>
            <to uri="mock:third"/>
        </multicast>
    </route>
</camelContext>

2.8.7. 기본 스레드 풀 프로필 설정

기본 스레드 풀은 기본 스레드 풀 프로필에서 설정을 사용하는 스레드 팩토리에 의해 자동으로 생성됩니다. 기본 스레드 풀 프로필에는 표 2.9. “기본 스레드 풀 프로필 설정” 에 표시된 설정이 있습니다(애플리케이션 코드에서 이러한 설정을 수정하지 않은 것으로 가정).

표 2.9. 기본 스레드 풀 프로필 설정

스레드 옵션기본값

maxQueueSize

1000

poolSize

10

maxPoolSize

20

keepAliveTime

60 (초)

rejectedPolicy

CallerRuns

2.8.8. 기본 스레드 풀 프로필 변경

모든 후속 기본 스레드 풀이 사용자 지정 설정으로 생성되도록 기본 스레드 풀 프로필 설정을 변경할 수 있습니다. Java 또는 Spring XML에서 프로필을 변경할 수 있습니다.

예를 들어 Java DSL에서는 다음과 같이 기본 스레드 풀 프로필에서 poolSize 옵션과 maxQueueSize 옵션을 사용자 지정할 수 있습니다.

// Java
import org.apache.camel.spi.ExecutorServiceManager;
import org.apache.camel.spi.ThreadPoolProfile;
...
ExecutorServiceManager manager = context.getExecutorServiceManager();
ThreadPoolProfile defaultProfile = manager.getDefaultThreadPoolProfile();

// Now, customize the profile settings.
defaultProfile.setPoolSize(3);
defaultProfile.setMaxQueueSize(100);
...

XML DSL에서는 다음과 같이 기본 스레드 풀 프로필을 사용자 지정할 수 있습니다.

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
    <threadPoolProfile
        id="changedProfile"
        defaultProfile="true"
        poolSize="3"
        maxQueueSize="100"/>
    ...
</camelContext>

이전 XML DSL 예에서 defaultProfile 속성을 true 로 설정하는 것이 중요합니다. 그러지 않으면 스레드 풀 프로파일은 기본 스레드 풀 프로필을 대체하는 대신 사용자 지정 스레드 풀 프로필로 처리됩니다( “사용자 정의 스레드 풀 프로필 생성”참조).

2.8.9. 프로세서의 스레드 풀 사용자 정의

executorService 또는 executorServiceRef 옵션을 사용하여 스레딩 인식 프로세서에 대한 스레드 풀을 더 직접 지정할 수도 있습니다(이러한 옵션은 parallelProcessing 옵션 대신 사용됨). 다음과 같이 프로세서의 스레드 풀을 사용자 지정하는 데 사용할 수 있는 두 가지 방법이 있습니다.

  • 사용자 지정 스레드 풀 Cryostat-단일적으로 ExecutorService (스레드 풀) 인스턴스를 생성하고 executorService 옵션에 전달합니다.
  • 사용자 지정 스레드 풀 프로필 Cryostat - Cryostatcreate을 지정하고 사용자 지정 스레드 풀 팩토리를 등록합니다. executorServiceRef 옵션을 사용하여 이 팩토리를 참조하는 경우 프로세서는 팩토리를 자동으로 사용하여 사용자 지정 스레드 풀 인스턴스를 생성합니다.

executorServiceRef 옵션에 빈 ID를 전달하면 스레드링 인식 프로세서는 먼저 레지스트리에서 해당 ID가 있는 사용자 지정 스레드 풀을 찾습니다. 해당 ID에 등록된 스레드 풀이 없는 경우 프로세서는 레지스트리에서 사용자 지정 스레드 풀 프로필을 조회하고 사용자 지정 스레드 풀 프로필을 사용하여 사용자 지정 스레드 풀을 인스턴스화합니다.

2.8.10. 사용자 정의 스레드 풀 생성

사용자 지정 스레드 풀은 java.util.concurrent.ExecutorService 유형의 스레드 풀일 수 있습니다. Apache Camel에서는 스레드 풀 인스턴스를 생성하는 방법을 사용하는 것이 좋습니다.

  • org.apache.camel.builder.ThreadPoolBuilder 유틸리티를 사용하여 스레드 풀 클래스를 빌드합니다.
  • 현재 CamelContextorg.apache.camel.spi.ExecutorServiceManager 인스턴스를 사용하여 스레드 풀 클래스를 생성합니다.

결국 ThreadPoolBuilderExecutorServiceManager 인스턴스를 사용하여 정의되기 때문에 두 가지 접근 방식에는 크게 차이가 없습니다. 일반적으로 ThreadPoolBuilder 는 더 간단한 접근 방식을 제공하기 때문에 선호됩니다. 그러나 ExecutorServiceManager 인스턴스에 직접 액세스하여 생성할 수 있는 스레드 종류( ScheduledExecutorService)가 하나 이상 있습니다.

표 2.10. “스레드 풀 빌더 옵션” 새 사용자 지정 스레드 풀을 정의할 때 설정할 수 있는 ThreadPoolBuilder 클래스에서 지원하는 옵션을 표시합니다.

표 2.10. 스레드 풀 빌더 옵션

빌더 옵션설명

maxQueueSize()

이 스레드 풀이 들어오는 작업 큐에 저장할 수 있는 최대 보류 중인 작업 수를 설정합니다. 값 -1 은 바인딩되지 않은 큐를 지정합니다. 기본값은 기본 스레드 풀 프로필에서 가져옵니다.

poolSize()

풀의 최소 스레드 수를 설정합니다(초기 풀 크기이기도 함). 기본값은 기본 스레드 풀 프로필에서 가져옵니다.

maxPoolSize()

풀에 있을 수 있는 최대 스레드 수를 설정합니다. 기본값은 기본 스레드 풀 프로필에서 가져옵니다.

keepAliveTime()

이 기간(초 단위로 지정)보다 오래 유휴 상태인 스레드가 있는 경우 종료됩니다. 이렇게 하면 로드가 켜지면 스레드 풀을 축소할 수 있습니다. 기본값은 기본 스레드 풀 프로필에서 가져옵니다.

rejectedPolicy()

들어오는 작업 큐가 가득 차면 수행할 작업을 지정합니다. 가능한 값은 다음 네 가지로 지정할 수 있습니다.

CallerRuns
(기본값) 가장 최근 들어오는 작업을 실행하도록 호출자 스레드를 가져옵니다. 이 옵션은 호출기 스레드가 최신 들어오는 작업 처리를 완료할 때까지 더 많은 작업을 수신하지 못하도록 합니다.
Abort
예외를 throw하여 가장 최근 들어오는 작업을 중단합니다.
삭제
가장 최근에 들어오는 작업을 자동으로 삭제합니다.
DiscardOldest
가장 오래 처리되지 않은 작업을 삭제한 다음 작업 큐에서 가장 최근에 들어오는 작업을 큐에 추가하려고 시도합니다.

build()

사용자 정의 스레드 풀 빌드를 완료하고 build() 에 대한 인수로 지정된 ID 아래에 새 스레드 풀을 등록합니다.

Java DSL에서는 다음과 같이 ThreadPoolBuilder 를 사용하여 사용자 지정 스레드 풀을 정의할 수 있습니다.

// Java
import org.apache.camel.builder.ThreadPoolBuilder;
import java.util.concurrent.ExecutorService;
...
ThreadPoolBuilder poolBuilder = new ThreadPoolBuilder(context);
ExecutorService customPool = poolBuilder.poolSize(5).maxPoolSize(5).maxQueueSize(100).build("customPool");
...

from("direct:start")
  .multicast().executorService(customPool)
    .to("mock:first")
    .to("mock:second")
    .to("mock:third");

다음과 같이 개체 참조 customPoolexecutorService() 옵션에 직접 전달하는 대신, Quarkus ID를 executorServiceRef() 옵션에 전달하여 레지스트리의 스레드 풀을 조회할 수 있습니다.

// Java
from("direct:start")
  .multicast().executorServiceRef("customPool")
    .to("mock:first")
    .to("mock:second")
    .to("mock:third");

XML DSL에서는 threadPool 요소를 사용하여 ThreadPoolBuilder 에 액세스합니다. 그런 다음 executorServiceRef 특성을 사용하여 사용자 지정 스레드 풀을 참조하여 다음과 같이 Spring 레지스트리에서 ID로 스레드 풀을 조회할 수 있습니다.

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
    <threadPool id="customPool"
                poolSize="5"
                maxPoolSize="5"
                maxQueueSize="100" />

    <route>
        <from uri="direct:start"/>
        <multicast executorServiceRef="customPool">
            <to uri="mock:first"/>
            <to uri="mock:second"/>
            <to uri="mock:third"/>
        </multicast>
    </route>
</camelContext>

2.8.11. 사용자 정의 스레드 풀 프로필 생성

생성할 사용자 지정 스레드 풀 인스턴스가 많은 경우 스레드 풀에 대해 팩토리 역할을 하는 사용자 지정 스레드 풀 프로필을 정의하는 것이 더 편리합니다. 스레드 인식 프로세서의 스레드 풀 프로필을 참조할 때마다 프로세서는 프로필을 자동으로 사용하여 새 스레드 풀 인스턴스를 만듭니다. Java DSL 또는 XML DSL에서 사용자 지정 스레드 풀 프로필을 정의할 수 있습니다.

예를 들어 Java DSL에서는 빈 ID, customProfile 을 사용하여 사용자 지정 스레드 풀 프로필을 생성하고 다음과 같이 경로 내에서 참조할 수 있습니다.

// Java
import org.apache.camel.spi.ThreadPoolProfile;
import org.apache.camel.impl.ThreadPoolProfileSupport;
...
// Create the custom thread pool profile
ThreadPoolProfile customProfile = new ThreadPoolProfileSupport("customProfile");
customProfile.setPoolSize(5);
customProfile.setMaxPoolSize(5);
customProfile.setMaxQueueSize(100);
context.getExecutorServiceManager().registerThreadPoolProfile(customProfile);
...
// Reference the custom thread pool profile in a route
from("direct:start")
  .multicast().executorServiceRef("customProfile")
    .to("mock:first")
    .to("mock:second")
    .to("mock:third");

XML DSL에서 threadPoolProfile 요소를 사용하여 사용자 지정 풀 프로필을 만듭니다(기본 스레드 풀 프로필이 아니므로 defaultProfile 옵션이 false 로 설정되도록 합니다). metrics ID, customProfile 을 사용하여 사용자 정의 스레드 풀 프로필을 생성하고 다음과 같이 경로 내에서 참조할 수 있습니다.

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
    <threadPoolProfile
                id="customProfile"
                poolSize="5"
                maxPoolSize="5"
                maxQueueSize="100" />

    <route>
        <from uri="direct:start"/>
        <multicast executorServiceRef="customProfile">
            <to uri="mock:first"/>
            <to uri="mock:second"/>
            <to uri="mock:third"/>
        </multicast>
    </route>
</camelContext>

2.8.12. 구성 요소 간 스레드 풀 공유

일부 표준 폴링 기반 구성 요소는 File 및 FTP해야 할 구성 요소와 같이 사용할 스레드 풀을 지정할 수 있습니다. 이를 통해 여러 구성 요소가 동일한 스레드 풀을 공유하여 JVM의 전체 스레드 수를 줄일 수 있습니다.

예를 들어 Apache Camel 구성 요소 참조 가이드의 File2 참조 가이드와 Apache Camel 구성 요소 참조 가이드Ftp2 는 구성 요소의 ExecutorService 오브젝트를 지정하는 데 사용할 수 있는 scheduledExecutorService 속성을 노출합니다.

2.8.13. 스레드 이름 사용자 정의

애플리케이션 로그를 더 읽기 쉽게 만들려면 종종 스레드 이름을 사용자 지정하는 것이 좋습니다(로그에서 스레드를 식별하는 데 사용됨). 스레드 이름을 사용자 지정하려면 ExecutorServiceStrategy 클래스 또는 ExecutorServiceManager 클래스에서 setThreadNamePattern 메서드를 호출하여 스레드 이름 패턴 을 구성할 수 있습니다. 또는 스레드 이름 패턴을 설정하는 더 쉬운 방법은 CamelContext 오브젝트에 threadNamePattern 속성을 설정하는 것입니다.

다음 자리 표시자는 스레드 이름 패턴에서 사용할 수 있습니다.

#camelId#
현재 CamelContext 의 이름입니다.
#counter#
증가 카운터로 구현된 고유 스레드 식별자입니다.
#name#
일반 Camel 스레드 이름입니다.
#longName#
끝점 매개 변수를 포함할 수 있는 긴 스레드 이름).

다음은 스레드 이름 패턴의 일반적인 예입니다.

Camel (#camelId#) thread #counter# - #name#

다음 예제에서는 XML DSL을 사용하여 Camel 컨텍스트에서 threadNamePattern 속성을 설정하는 방법을 보여줍니다.

<camelContext xmlns="http://camel.apache.org/schema/spring"
              threadNamePattern="Riding the thread #counter#" >
  <route>
    <from uri="seda:start"/>
    <to uri="log:result"/>
    <to uri="mock:result"/>
  </route>
</camelContext>