2014년 spring batch에서 spring retry로 따로 분리되었다. Spring 4이상에서 사용할 수 있다.

(계속 유지보수는 안되고 있는 느낌이지만 유틸리티의 성격이 있어서 간단한 코드에서는 계속 쓸 수 있을 듯 싶다.)



https://github.com/spring-projects/spring-retry

예제만 봐도 깔끔한 느낌이다.

@Configuration
@EnableRetry
public class Application {

    @Bean
    public Service service() {
        return new Service();
    }

}

@Service
class Service {
    @Retryable(RemoteAccessException.class)
    public void service() {
        // ... do something
    }
    @Recover
    public void recover(RemoteAccessException e) {
       // ... panic
    }
}



Retry를 간단하게 아래와 같이 코딩할 수 있다. 

RetryTemplate template = new RetryTemplate();

template.setRetryPolicy(new SimpleRetryPolicy(2));

final ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();

backOffPolicy.setInitialInterval(20L);

template.setBackOffPolicy(backOffPolicy);

 

template.execute(new RetryCallback<String>() {

  @Override

  public String doWithRetry(final RetryContext context) throws Exception {

    return "";

  }

});


괜찮은 코드는 아래 코드를 추천한다.

https://dzone.com/articles/spring-retry-ways-integrate

http://www.java-allandsundry.com/2014/12/spring-retry-ways-to-integrate-with.html

https://github.com/bijukunjummen/test-spring-retry


간단하게 테스트를 할 수 있는 예제로 테스트해봤다. 2 번 retry를 바로 하는 구조의 호출을 다음과 같이 개발해볼 수 있다. 

public interface RemoteCallService {
@Retryable(maxAttempts = 2, backoff = @Backoff(delay = 0))
String call(String url);
}


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringRetryTest {

@Autowired
private RemoteCallService remoteCallService;

@Test
public void testRetry() {
String message = this.remoteCallService.call("http://social.google.com");
verify(remoteCallService, times(2)).call("http://social.google.com");
System.out.println(message);
assertThat(message, is("OK"));
}

@Configuration
@EnableRetry
public static class SpringConfig {

@Bean
public RemoteCallService remoteCallService() throws Exception {
RemoteCallService remoteService = mock(RemoteCallService.class);
when(remoteService.call("http://social.google.com"))
.thenThrow(new RuntimeException("Remote Exception 1"))
.thenReturn("OK");
return remoteService;
}
}
}


Spring RestTemplate의 retry를 spring retry를 이용해서 개발해보았더니. 괜찮아 보였다. 테스트 코드까지 깔끔해진다. 


Posted by '김용환'
,