2012-01-17 86 views
3

我是Spring Integration的新手。彈簧集成2與石英調度器

我已經配置了Spring文件入站通道適配器,例如,

<file:inbound-channel-adapter channel="channel1" directory="${location}" prevent-duplicates="true" filename-pattern="*.csv"> 
     <si:poller> 
      <si:interval-trigger interval="1000"/> 
     </si:poller> 
</file:inbound-channel-adapter> 

<si:service-activator input-channel="channel1" output-channel="channel2" ref="filenameGenerator" method="generate"/> 

現在這工作正常。 但是這需要部署在集羣環境中。我想確保羣集中的多個實例不會嘗試讀取同一個文件。那麼這樣的工作會在這樣的環境下進行?

如果沒有,我可以使用Quartz調度這樣的:

<file:inbound-channel-adapter channel="channel1" directory="${location}" prevent-duplicates="true" filename-pattern="*.csv"> 
      <si:poller task-executor="taskExecutor" fixed-rate="1000"/> 
    </file:inbound-channel-adapter> 

    <si:service-activator input-channel="channel1" output-channel="channel2" ref="filenameGenerator" method="generate"/> 

    <bean id="taskExecutor" class="org.springframework.scheduling.quartz.SimpleThreadPoolTaskExecutor"> 
     <property name="threadCount" value="20"/> 
     <property name="threadNamePrefix" value="consumer"/> 
    </bean> 

將這項工作與解決我的問題? 或者我必須使用交易?

我希望問題很清楚。

感謝, 阿迪

+0

再次重申這個問題, 問題是與文件在集羣環境中入站通道適配器。當一個文件被放置在一個文件夾中時,它應該被拾取,處理並最終重命名它。 在羣集中,雖然一個實例選取特定文件並仍在處理它,但另一個節點的文件適配器也會啓動並嘗試處理。第二個適配器失敗,出現文件未找到異常,作爲第一個適配器進程並在此期間重命名。那麼,我能做些什麼,這不會發生? – adi 2012-01-17 16:34:04

回答

2

當多個進程從同一目錄讀取它可以 需要鎖定文件,以防止它們被拾起 兼任。要做到這一點,您可以使用FileLocker

查看文件櫃here附近的文檔。看來,你可以做soemthing這樣的:

<file:inbound-channel-adapter ... > 
    <file:nio-locker/> 
</file:inbound-channel-adapter> 

當多個進程從同一目錄讀取它可以 需要鎖定文件,以防止它們被拾起 兼任。要做到這一點,您可以使用FileLocker

+0

我現在得到這個錯誤:java.io.IOException:進程無法訪問文件,因爲另一個進程已經鎖定了一部分文件...我有另一個通道重命名文件... – adi 2012-01-17 17:59:49

1

要確保石英計劃的作業在羣集內執行一次且只執行一次,請配置持久的羣集石英作業計劃。這裏有一個樣本配置,爲石英1.6.6:

<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
    <!--  Set whether any jobs defined on this SchedulerFactoryBean should 
      overwrite existing job definitions. 
     --> 
    <property name="overwriteExistingJobs" value="true" /> 
    <property name="dataSource" ref="myTransactionalDataSource" /> 

<!-- nonTransactionalDataSource is only necessary with clustered Quartz with an XA DataSource. 
    --> 
    <property name="nonTransactionalDataSource" ref="myNonTransactionalDataSource" /> 

<property name="quartzProperties"> 
    <props> 
    <prop key="org.quartz.jobStore.selectWithLockSQL">SELECT * FROM {0}LOCKS WITH(UPDLOCK,HOLDLOCK) WHERE LOCK_NAME = ?</prop> 
    <!-- 
    Run in cluster. Quartz ensures persisted jobs are executed once within the 
         cluster 
    --> 
    <prop key="org.quartz.jobStore.isClustered">true</prop> 

<!-- Each node in the cluster must have a unique instance id. 
    --> 
    <prop key="org.quartz.scheduler.instanceId">AUTO</prop> 
<!-- Default clusterCheckinInterval is 15000 
    --> 
    <!-- <prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop> 
    --> 
</props> 
    </property> 
    <property name="transactionManager" ref="transactionManager" /> 
- <!-- 
     In Quartz 1.6.6, Quartz's ThreadPool interface is used when firing job triggers, 
     in org.quartz.core.QuartzSchedulerThread. 
     Quartz 1.x still starts some unmanaged threads, notably org.quartz.impl.jdbcjobstore.JobStoreSupport's 
     ClusterManager which is used when clustered=true. Quartz 2.0 should correct this problem.  
    --> 
    <property name="taskExecutor" ref="myTaskExecutor" /> 
    </bean>