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를 이용해서 개발해보았더니. 괜찮아 보였다. 테스트 코드까지 깔끔해진다.
'general java' 카테고리의 다른 글
[spring mongodb] mongodb 색인 추가/삭제 및 jpa로 새로운 색인 생성하기 (2차 색인) (0) | 2015.10.08 |
---|---|
[spring boot] l7check 막코드 + nginx 설정 (0) | 2015.10.05 |
[spring] p와 c 노테이션으로 spring rest template을 간결하게 사용하기 (0) | 2015.10.05 |
[spring] LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods 해결하기 (0) | 2015.10.01 |
[spring boot] 기본 log 쓰지 않고, logback 사용할 수 있도록 추가하기 (0) | 2015.09.30 |