Serhii
Serhii

Reputation: 7563

Spring Batch how to configure retry period for failed jobs

I need to deliver some messages with high guarantee. This messages should be delivered as limited collections (100 at least as example). To resolve my task I think I should use spring batch. I need to configure exponentially increasing time for each next failed attempt. Each data object should have 5 delivery attempts as max. I expect to have a chance monitor all attempts and next retry time via db. Spring batch provides prepared tables for that. It seems my flow have only one job, but checking schema we can find that job only has status completion status (not payload): enter image description here

Also there are neither attempts count no next execution time.

Issues:

I'm not clear how to configure retry period strategy. Should I use different tool (like quartz) or I need dive deeper into spring batch? I do not want make my own solution for this task, it seems like ordinal and should have elegant solution.

Upvotes: 2

Views: 2702

Answers (1)

Mahmoud Ben Hassine
Mahmoud Ben Hassine

Reputation: 31720

Once you defined your job and how to execute it, you can use Spring Retry which provides an ExponentialBackOffPolicy out of the box. Here is an example:

import java.time.LocalDateTime;

import org.junit.Test;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;

public class RetryTemplateTest {

    private Job job; // under test, has to be initialized

    @Test
    public void testExponentialBackoff() throws Exception {
        // configure backoff policy
        ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
        exponentialBackOffPolicy.setInitialInterval(1000);
        exponentialBackOffPolicy.setMultiplier(2.0);
        exponentialBackOffPolicy.setMaxInterval(10000);

        // configure retry policy
        SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
        simpleRetryPolicy.setMaxAttempts(5);

        // configure retry template
        RetryTemplate retryTemplate = new RetryTemplate();
        retryTemplate.setBackOffPolicy(exponentialBackOffPolicy);
        retryTemplate.setRetryPolicy(simpleRetryPolicy);

        // run the job with retry on failure
        retryTemplate.execute(new RetryCallback<JobExecution, Exception>() {
            @Override
            public JobExecution doWithRetry(RetryContext context) throws Exception {
                return run(job);
            }
        });
    }

    private JobExecution run(Job job) throws Exception {
        System.out.println(LocalDateTime.now() + ": running job");
        if (true) { // just for test
            throw new Exception("Job failed");
        }
        return null;
    }
}

This example prints:

2019-03-13T09:19:21.882: running job
2019-03-13T09:19:22.892: running job
2019-03-13T09:19:24.893: running job
2019-03-13T09:19:28.894: running job
2019-03-13T09:19:36.895: running job

java.lang.Exception: Job failed

As you can see, the retry template has launched the job at seconds 21, 22, 24, 28 and 36 and retried the job at most 5 times before failing.

Hope this helps.

Upvotes: 2

Related Questions