8.12. Jakarta Enterprise Beans-clustered 데이터베이스 타이머

JBoss EAP는 클러스터형 환경에서 Jakarta Enterprise Bean 타이머를 유지하기 위해 클러스터형 데이터베이스 지원 타이머를 지원합니다. 클러스터링이 데이터베이스를 통해 제공되기 때문에 짧은 시간 내에 타이머 수가 꺼지면 성능이 저하됩니다. ejb3/service=timer-service/database -data -store 구성 요소의 refresh-interval 및 allow- execution 특성을 사용하여 성능을 최적화할 수 있습니다.

다음과 같이 비클러스터형 모드에서 데이터베이스 타이머를 사용할 수도 있습니다.

  • refresh-interval0 으로 설정합니다.
  • 모든 노드에 고유한 파티션 이름을 제공하거나 각 노드에 다른 데이터베이스를 사용합니다.

Jakarta Enterprise Beans-clustered 데이터베이스 타이머는 다음과 같이 작동합니다.

  • 타이머를 실행할 수 있는 모든 노드는 알고 있는 모든 타이머에 대한 시간 초과를 예약합니다.
  • 이 시간 초과가 만료되면 각 노드는 상태를 running으로 업데이트하여 타이머를 잠그려고 시도합니다.

    상태 업데이트 쿼리는 다음 쿼리와 유사합니다.

    UPDATE JBOSS_EJB_TIMER SET TIMER_STATE=? WHERE ID=? AND TIMER_STATE<>? AND NEXT_DATE=?;

트랜잭션과 READ_COMMITTED 또는 SERIALIZABLE 격리 모드를 사용하므로 행 업데이트에는 하나의 노드만 성공적으로 수행되며 타이머가 실행되는 노드입니다.

8.12.1. 자카르타 Enterpise Bean-clustered 타이머 설정

데이터베이스 지원 타이머 저장소를 추가하여 Jakarta Enterprise Beans-clustered 타이머를 설정할 수 있습니다.

사전 요구 사항

  • 데이터베이스는 READ_COMMITTED 또는 SERIALIZABLE 격리 모드를 지원해야 합니다.

절차

  • 데이터베이스 지원 타이머 저장소를 생성합니다.

    /subsystem=ejb3/service=timer-service/database-data-store=my-clustered-store:add(allow-execution=true, datasource-jndi-name="java:/MyDatasource", refresh-interval=60000, database="postgresql", partition="mypartition")

    다음과 같이 매개변수를 설정합니다.

    • allow-execution : 이 노드에서 타이머를 실행할 수 있도록 하려면 true 로 설정합니다. false 로 설정하면 JBoss EAP는 이 노드의 타이머를 다른 노드의 데이터베이스에 추가합니다. 타이머 실행을 클러스터의 몇 개 노드로만 제한하면 전체 데이터베이스 로드가 줄어듭니다.
    • datasource-jndi-name : 사용할 데이터 소스입니다.
    • refresh-interval : 이 노드가 데이터베이스에 다른 노드에서 추가한 새 타이머가 있는지 확인하기 전에 경과해야 하는 기간을 설정합니다. 값은 밀리초 단위입니다.

      중요

      작은 값을 설정하면 JBoss EAP에서 타이머를 더 빨리 선택하지만 데이터베이스의 에서 부하가 증가합니다. 타이머를 추가한 노드가 실패했거나 allow-execution 이 false이므로 타이머를 실행할 수 없는 경우 노드가 새로 고쳐질 때까지 타이머가 실행되지 않을 수 있습니다.

    • database : 사용 중인 데이터베이스 유형을 정의합니다. 일부 SQL 문은 데이터베이스에서 사용자 지정합니다.

      이 속성을 정의하지 않으면 서버에서 유형을 자동으로 탐지하려고 합니다. 현재 지원되는 유형은 postgresql,mysql,oracle,db2,hsqlh2 입니다.

      SQL은 다음 파일에 있습니다. modules/system/layers/base/org/jboss/as/ejb3/main/timers/timer-sql.properties

      이 파일에 새 데이터베이스별 SQL 문을 추가하여 실행되는 SQL을 수정하거나 새 데이터베이스에 대한 지원을 추가할 수 있습니다.

    • partition : 이 노드가 포함될 파티션의 이름으로 값을 설정합니다. 동일한 파티션에 있는 노드의 타이머만 이 노드에 표시됩니다. 성능 향상을 위해 대규모 클러스터를 여러 개의 작은 클러스터로 분리하려면 이 속성을 사용합니다.
참고

클러스터되지 않은 타이머에 이 데이터베이스 데이터 저장소를 사용하려면 새로 고침 인터럽트를 0으로 설정하고 모든 노드에 고유한 파티션 이름이 있는지 확인하거나 각 노드에 다른 데이터베이스를 사용합니다.

8.12.2. 배포 시 Jakarta Enterprise Beans-clustered 타이머 사용

단일 데이터 저장소를 모든 애플리케이션의 기본값으로 사용하거나 각 애플리케이션에 특정 데이터 저장소를 사용할 수 있습니다.

사전 요구 사항

  • Jakarta Enterprise Beans-clustered 데이터베이스 지원 타이머 저장소를 설치했습니다.

절차

  • 단일 데이터 저장소를 모든 애플리케이션의 기본값으로 사용하려면 다음과 같이 ejb3 하위 시스템 내의 default-data-store 를 업데이트합니다.

    <timer-service thread-pool-name="timer" default-data-store="clustered-store">
        <data-stores>
            <database-data-store name="clustered-store" datasource-jndi-name="java:jboss/datasources/ExampleDS" partition="timer"/>
        </data-stores>
    </timer-service>
  • 특정 애플리케이션에 별도의 데이터 저장소를 사용하려면 jboss-ejb3.xml 파일에서 타이머 데이터 저장소 이름을 설정합니다.

    <?xml version="1.1" encoding="UTF-8"?>
    <jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:timer="urn:timer-service:1.0" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" version="3.1" impl-version="2.0">
        <assembly-descriptor>
            <timer:timer>
                <ejb-name>*</ejb-name>
                <timer:persistence-store-name>my-clustered-store</timer:persistence-store-name>
            </timer:timer>
        </assembly-descriptor>
    </jboss:ejb-jar>

8.12.3. Jakarta Interceptors를 사용하여 Jakarta Enterprise Bean-clustered 타이머 새로 고침

새로 고침 간격이 만료되기 전에 타이머를 새로 고치도록 비즈니스 방법에 Jakarta Interceptor를 설정하여 타이머를 프로그래밍 방식으로 새로 고칠 수 있습니다.

참고

클러스터형 배포에서는 여러 노드가 짧은 간격으로 데이터 저장소를 업데이트하면 메모리 내 타이머 상태가 일시적으로 동기화되지 않을 수 있습니다.

사전 요구 사항

  • 데이터베이스 지원 클러스터형 Jakarta Enterprise Bean을 구성했습니다.

절차

  1. wildfly.ejb.timer.refresh.enabledtrue 로 활성화하는 Jakarta Interceptors를 구현합니다.

    import javax.interceptor.AroundInvoke;
    import javax.interceptor.Interceptor;
    import javax.interceptor.InvocationContext;
    
    /**
     * An interceptor to enable programmatic timer refresh across multiple nodes.
     */
    @Interceptor
    public class RefreshInterceptor {
        @AroundInvoke
        public Object intercept(InvocationContext context) throws Exception {
            context.getContextData().put("wildfly.ejb.timer.refresh.enabled", Boolean.TRUE);
            return context.proceed();
        }
    }
  2. 자카르타 인터셉터 구성.

    • 대상 상태 비저장 또는 Singleton 빈 비즈니스 방법으로 자카르타 인터셉터를 구성할 수 있습니다. When wildfly.ejb.timer.refresh.enabledtrue 로 설정되어 타이머를 반환하기 전에 TimerService.getAllTimers() 를 호출하여 타이머 데이터 저장소를 새로 고칩니다.

      @Singleton
      public class RefreshBean1 ... {
      
          @Interceptors(RefreshInterceptor.class)
          public void businessMethod1() {
              ...
              // since wildfly.ejb.timer.refresh.enabled is set to true in interceptor for this business method,
              // calling timerService.getAllTimers() will first refresh from timer datastore before returning timers.
              final Collection<Timer> allTimers = timerService.getAllTimers();
              ...
          }
      }
    • 또는 전용 비즈니스 방법을 구현하여 필요한 경우 애플리케이션의 다른 부분이 호출하는 타이머를 프로그래밍 방식으로 새로 고칠 수 있습니다.

          @Interceptors(RefreshInterceptor.class)
          public List<Timer> getAllTimerInfoWithRefresh() {
              return timerService.getAllTimers();
          }
      
          public void businessMethod1() {
              final LocalBusinessInterface businessObject = sessionContext.getBusinessObject(LocalBusinessInterface.class);
              businessObject.getAllTimerInfoWithRefresh();
      
              // timer has been programmatically refreshed from datastore.
              // continue with other business logic...
          }