복붙노트

[SPRING] 스프링 통합 + cron + 쿼츠 클러스터?

SPRING

스프링 통합 + cron + 쿼츠 클러스터?

다음과 같은 cron 표현식에 의해 트리거되는 스프링 통합 흐름이 있습니다.

<int-ftp:inbound-channel-adapter id="my-input-endpoint" ...>
    <int:poller trigger="my-trigger"/>
</int-ftp:inbound-channel-adapter>

<bean id="my-trigger"
   class="org.springframework.scheduling.support.CronTrigger">
  <constructor-arg value="0 * * * * *" />
</bean>

그것은 잘 작동합니다. 하지만 이제 구현을 확장하여 클러스터를 준비해야합니다 (동일한 시점에서 하나의 클러스터 노드에서만 작업이 실행 됨).

클러스터 모드에서 Quartz 프레임 워크를 사용하여 (데이터베이스에서 작업 상태 유지)이 통합 플로우를 트리거하는 것이 바람직하다. Quartz는 멋진 솔루션을 제공합니다. 유일한 문제는 Quartz를 기존의 in-out-channer-adapter와 통합하는 방법입니다. "poller"의 "trigger"속성은 org.springframework.scheduling.Trigger의 서브 클래스만을 받아 들인다. "poller trigger"와 Quartz 프레임 워크 사이에 다리를 찾을 수 없었습니다.

미리 많은 감사드립니다!

해결법

  1. ==============================

    1.여기 하나의 방법이 있습니다 ...

    여기 하나의 방법이 있습니다 ...

    인바운드 어댑터의 자동 시작 특성을 false로 설정하십시오.

    한 번만 발동하는 사용자 정의 트리거를 즉시 생성하십시오.

    public static class FireOnceTrigger implements Trigger {
    
        boolean done;
    
        public Date nextExecutionTime(TriggerContext triggerContext) {
            if (done) {
                return null;
            }
            done = true;
            return new Date();
        }
    
        public void reset() {
            done = false;
        }
    }
    

    석영 작업에서 트리거 및 SourcePollingChannelAdapter에 대한 참조를 가져옵니다.

    석영 트리거가 터지면 석영 작업을하십시오.

  2. ==============================

    2.게리 (Gary)의 해결책이 나온다. 이 내 봄 컨텍스트 :

    게리 (Gary)의 해결책이 나온다. 이 내 봄 컨텍스트 :

    <int-ftp:inbound-channel-adapter id="my-endpoint"
            auto-startup="false">
        <int:poller trigger="my-endpoint-trigger"/>
    </int-ftp:inbound-channel-adapter>
    
    
    <bean id="my-endpoint-trigger" class="com.my.FireOnceTrigger"/>
    
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    
        <property name="triggers">
            <list>
                <ref bean="my-job-trigger" />
            </list>
        </property>
    
        <property name="schedulerContextAsMap">
            <map>
                <entry key="inputEndpoint"><ref bean="my-input-endpoint" /></entry>
                <entry key="inputEndpointTrigger"><ref bean="my-endpoint-trigger" /></entry>
            </map>
        </property>
    </bean>
    
    <bean id="my-job-trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="cronExpression" value="0 * * * * ?" />
        <property name="jobDetail" ref="my-job" />
    </bean>
    
    <bean name="my-job" class="org.springframework.scheduling.quartz.JobDetailBean">
        <property name="jobClass" value="com.my.MyActivatorJob " />
    </bean>
    

    및 MyActivatorJob 클래스 :

    public class MyActivatorJob extends QuartzJobBean implements {
    
    private AbstractEndpoint inputEndpoint;
    
    private FireOnceTrigger inputEndpointTrigger;
    
    public void setInputEndpoint(final AbstractEndpoint pInputEndpoint) {
        this.inputEndpoint = pInputEndpoint;
    }
    
    public void setInputEndpointTrigger(final FireOnceTrigger pInputEndpointTrigger) {
        this.inputEndpointTrigger = pInputEndpointTrigger;
    }
    
    @Override
    protected void executeInternal(final JobExecutionContext pParamJobExecutionContext)
    throws JobExecutionException {
    
        inputEndpoint.stop();
        inputEndpointTrigger.reset();
        inputEndpoint.start();
    }
    

    }

    다음 단계로서이 봄 컨텍스트는 schedulerContextAsMap의 사용을 좀 더 융통성있게 대체하고 많은 다른 끝점을 활성화 및 비활성화하는 더 많은 작업을 정의 할 수 있도록 리팩토링해야합니다.

    지금까지 Gary에게 감사드립니다!

  3. ==============================

    3.당신이 제안한 것처럼 석영과 봄을 통합하려했지만 다른 두 가지 문제에 직면했습니다 :

    당신이 제안한 것처럼 석영과 봄을 통합하려했지만 다른 두 가지 문제에 직면했습니다 :

    1.) Quartz 2.x와 Spring 3.x 사용시 IncompatibleClassChangeError 예외. 그것은 알려진 문제이지만 그 해결책을 찾지 못했습니다.

    2) 다른 스프링 빈을 Quartz 작업 인스턴스에 삽입한다. 나는 해결책을 찾았지만 아무도 나를 위해 일하지 않는다. 나는 그것을 사용하여 하나를 시도했습니다.

    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="jobFactory">
            <bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory" />
        </property>
    
        <property name="triggers">
            ...
        </property>
    
        <property name="schedulerContextAsMap">
            <map>
                <entry key="inputEndpoint" value-ref="my-endpoint" />
            </map>
        </property>
    </bean>
    

    작업에 다른 빈을 주입하지만이 속성을 SchedulerFactoryBean에 추가 한 후에는 작업이 실행되고 있지 않습니다 (예외가 표시되지 않음). "schedulerContextAsMap"속성을 제거하면 작업이 다시 실행됩니다.

  4. ==============================

    4.나는 그것을 시도하지 않았지만 Quartz 2와 Spring 호환성 문제가 Spring 3.1.1에서 수정 된 것 같다. https://jira.springsource.org/browse/SPR-8889를 참조하십시오.

    나는 그것을 시도하지 않았지만 Quartz 2와 Spring 호환성 문제가 Spring 3.1.1에서 수정 된 것 같다. https://jira.springsource.org/browse/SPR-8889를 참조하십시오.

  5. from https://stackoverflow.com/questions/11563469/spring-integration-cron-quartz-in-cluster by cc-by-sa and MIT license