2015-02-10 92 views
1

我想在我的彈簧啓動應用程序中使用彈簧批處理。我有一個用例來在一天中的某個時間段內停止工作,一旦時間窗口過去,我想從暫停的步驟重新開始工作。時至今日,我已經想通了,有如下圖所示類這樣的方法有兩種:春季批處理重啓持久存儲作業註冊作業

jobRepository和jobExplorer都是由永久存儲支持的
class JobStarter { 
    @Autowired protected JobLauncher jobLauncher 
    @Autowired protected JobRegistry jobRegistry 
    @Autowired protected JobOperator jobOperator 
    @Autowired protected JobExplorer jobExplorer 

    def startJob(Map config) { 
    Job job = build(config, subject) // build the job programmatically 
    JobParameters jobParameters = createJobParameters(subject, config) 
    jobLauncher.launch (job, jobParameters) 
    jobRegistry.register(new ReferenceFactory(job)) 
    } 

    def restartJob1(String jobName, JobParameters jobParameters) { 
    Job job = jobRegistry.getJob(jobName) 
    jobLauncher.launch (job, jobParameters) 
    } 

    // OR 

    def restartJob2(String jobName) { 
    def jobInstances = jobExplorer.getJobInstances(jobName, 0, 1) 
    if (!jobInstances) { 
     throw new Exception("Unable to find the job to restart") 
    } 
    def jobInstance = jobInstances[0] 
    jobOperator.restart(jobInstance.instanceId) 
    } 
} 

我有自定義實現。

我不能使用由Spring批處理提供的JobRegistry的默認實現,因爲它由內存映射支持,並且如果服務器關閉,jobRegistry爲空,因此重新啓動暫停的作業失敗。我想實現JobRegistry但問題是,我有一個困難時期我的自定義實現jobRegistry內持續工作的工廠:

class PersistentJobRegistry implements JobRegistry { 

    // Other methods and code omitted for brevity 
    static ObjectMapper mapper 
    static { 
    mapper = new ObjectMapper() 
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 
    mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) 
    mapper.enableDefaultTyping() 
    } 

    @Override 
    void register(JobFactory jobFactory) throws DuplicateJobException { 
    String jobFactoryStr = mapper.writeValueAsString(jobFactory) 
    save(jobFactory.getJobName(), jobFactoryStr) // saves jobFactoryStr to store 
    } 

    @Override 
    Job getJob(String name) throws NoSuchJobException { 
    String jobFactoryStr = get(name) // gets a serialized factory from store 
    JobFactory jobFactory = mapper.readValue(jobFactoryStr, JobFactory.class) 
    return jobFactory.createJob() 
    } 
} 

同時節約,我拿這個作爲jobFactoryStr,這顯然不會工作,因爲只有JOBNAME和有關作業沒有其他的信息和它的步驟:

jobFactoryStr = {"jobName":"MyJob:f6892e89-4a76-4395-ba0a-ca82b477a407"} 

我得到以下錯誤getJob()太:

com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class org.springframework.batch.core.configuration.JobFactory 
at [Source: {"jobName":"Pipeline:api:testing:c3241e19-4f32-474f-90d2-2974b672c183"}; line: 1, column: 1] 
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148) 
    at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:854) 
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._locateTypeId(AsArrayTypeDeserializer.java:122) 
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:93) 
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromObject(AsArrayTypeDeserializer.java:58) 
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserializeWithType(AbstractDeserializer.java:132) 
    at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:41) 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066) 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2161) 

我有兩個問題:

  1. 是我重新開始工作正確的做法?

  2. 我的jobRegistry實現方法是否正確?以上傑克遜錯誤會發生什麼問題?

+0

「JobRegistry」從哪裏啓動? – 2015-02-11 17:24:01

+0

@Michael,它是在spring中注入的,因爲一個bean(實現MapJobRegistry的東西存在於spring-batch jar中)。你在問什麼? – user788052 2015-02-12 00:00:17

+0

我問,因爲你說你不能使用基於地圖的註冊表,因爲如果服務器崩潰它將是空的。我假設在重新啓動時註冊表將被重新填充,以便在不需要持久性的情況下恢復狀態。 – 2015-02-12 16:57:33

回答

0

內置的招聘信息庫可以被任何RDBMS進行備份,你不需要雕琢自己的..默認情況下它被配置爲指向的內存數據庫,但它的問題更改屬性文件中的配置。

通過數據源定義,從job-repository標籤開始向後搜索彈簧上下文和屬性文件。將數據源指向目標數據庫。

用於爲最常用的RDBMS創建表的DDL嵌入到jar中,通常spring-batch會在首次啓動彈出窗口時負責創建表(在您的DEV環境中)批量作業。

請參閱http://docs.spring.io/spring-batch/reference/html/configureJob.html

+0

我「需要」使用redis代替RDBMS。所以這就是定製實現JobRepository的原因。 – user788052 2015-02-11 23:58:54