Springboot @retryable 재시도 안 함
다음 코드는 재시도되지 않습니다.제가 무엇을 빠뜨리고 있나요?
@EnableRetry
@SpringBootApplication
public class App implements CommandLineRunner
{
.........
.........
@Retryable()
ResponseEntity<String> authenticate(RestTemplate restTemplate, HttpEntity<MultiValueMap<String, String>> entity) throws Exception
{
System.out.println("try!");
throw new Exception();
//return restTemplate.exchange(auth_endpoint, HttpMethod.POST, entity, String.class);
}
pom.xml에 다음과 같이 추가하였습니다.
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
또한 @Retryable에 다른 인수 조합을 제공하려고 했습니다.
@Retryable(maxAttempts=10,value=Exception.class,backoff=@Backoff(delay = 2000,multiplier=2))
감사해요.
스프링 부트 2.0.2 릴리스에서는, 이 릴리스가@Retryable
는, 같은 클래스에 재시도 가능한 메서드와 콜된 메서드가 있는 경우는 동작하지 않습니다.디버깅 시 포인트 컷이 올바르게 구축되지 않았습니다.현시점에서는, 이 문제의 회피책은, 다른 클래스에 메서드를 써, 콜 할 필요가 있습니다.
여기서 작업 예를 찾을 수 있습니다.
를 위해@Retryable
발견될 방법에 대한 주석은 초기화된 컨텍스트에서 정확하게 호출되어야 한다.이 메서드는 스프링 컨텍스트에서 빈에서 호출됩니까, 아니면 다른 방법으로 호출됩니까?
테스트의 경우, 이것은 Runner가 사용하고 있는SpringJunit4ClassRunner
?
Spring의 @Retryable, @Cacheable, @Transaction 등은 모두 Aspect Oriented Programming을 사용하여 구현됩니다.스프링은 프록시 기반 위빙을 통해 AOP를 구현합니다.프록시는 어떤 빈에서 다른 빈으로의 콜을 대행 수신합니다.프록시는 오브젝트 메서드에서 다른 오브젝트 메서드로의 콜을 대행 수신할 수 없습니다.이것은 프록시 기반의 직조에는 일반적으로 제한이 있습니다.
다음 솔루션은 이 제한에 대처합니다.1 ) 상기와 같이 @Autowired(또는 @Resource)를 사용하여 자기 참조가 있는 빈을 주입합니다.이 참조에 대한 콜은 프록시를 전송합니다.2) Spring 기본 프록시 기반 위빙 대신 AspectJ의 ClassLoader를 사용합니다.3) 위와 같이 각각의 콩에 방법들을 담는다.여러 가지 상황에서 해 봤는데 각각 장단점이 있어요.
내가 풀었어.재시도하는 메서드에서 무언가를 반환하면 @Retryable()이 작동하지 않는다는 것을 알게 되었습니다.
pom.xml의 maven 의존성
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.5.RELEASE</version>
</dependency>
스프링 부트 어플리케이션자바
@SpringBootApplication
@EnableTransactionManagement
@EnableRetry
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
incontroller.disclos에 있습니다.
@RestController
public class JavaAllDataTypeController {
@Autowired
JavaAllDataTypeService JavaAllDataTypeService;
@RequestMapping(
value = "/springReTryTest",
method = RequestMethod.GET
)
public ResponseEntity<String> springReTryTest() {
System.out.println("springReTryTest controller");
try {
JavaAllDataTypeService.springReTryTest();
} catch (Exception e) {
e.printStackTrace();
}
return new ResponseEntity<String>("abcd", HttpStatus.OK);
}
}
현역의자바
@Service
@Transactional
public class JavaAllDataTypeService {
// try the method 9 times with 2 seconds delay.
@Retryable(maxAttempts=9,value=Exception.class,backoff=@Backoff(delay = 2000))
public void springReTryTest() throws Exception {
System.out.println("try!");
throw new Exception();
}
}
output: 9번 시도하고 예외를 발생시킵니다.
나는 원래 질문에서 설명한 것과 정확히 같은 문제를 가지고 있었다.
내 경우엔, 알고보니spring-boot-starter-aop
종속성이 우연히 포함되지 않았습니다.내꺼에 추가한 후pom.xml
,나의@Retryable
방법은 예상대로 동작했습니다.
값 반환원@Retryable
방법이 잘 통합니다.
반품 타입에도 대응합니다.
@Service
public class RetryService {
private int count = 0;
// try the method 9 times with 2 seconds delay.
@Retryable(maxAttempts = 9, value = Exception.class, backoff = @Backoff(delay = 2000))
public String springReTryTest() throws Exception {
count++;
System.out.println("try!");
if (count < 4)
throw new Exception();
else
return "bla";
}
}
하고 분@Retryable
같은 반에 있는 블록은 이렇게 할 수 있습니다.
여기서 중요한 것은 직접 자기주입 콩을 통해 메서드를 호출하지 않는 것입니다.
@Slf4j
@Service
public class RetryService {
@Resource(name = "retryService")
private RetryService self;
public String getValue(String appender) {
return self.getData(appender);
}
@Retryable(value = NumberFormatException.class, maxAttempts = 4, backoff = @Backoff(500))
public String getData(String appender) {
log.info("Calling getData");
Integer value = Integer.parseInt(appender);
value++;
return value.toString();
}
@Recover
public String recoverData(String appender) {
log.info("Calling recoverData");
return "DEFAULT";
}
}
재시도 사용에 대한 자세한 내용은 여기를 참조하십시오.
RetryTemplate
@Bean
public RetryTemplate retryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(2000l);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(2);
retryTemplate.setRetryPolicy(retryPolicy);
return retryTemplate;
}
그리고.
retryTemplate.execute(new RetryCallback<Void, RuntimeException>() {
@Override
public Void doWithRetry(RetryContext arg0) {
myService.templateRetryService();
...
}
});
나를 위해 운동했다.
꽤 오래된 스레드지만 메서드의 가시성을 변경한 후 공유하려고 합니다.private
로로 합니다.public
,Retryable
정상적으로 재시도하고 있습니다.
이는 위에서 언급한 셀프 리소스를 사용하는 것 외에 추가로 적용됩니다.
저도 같은 문제에 직면했지만, 나중에 조사와 조사를 통해 위의 @Retryable 주석과 함께 클래스 위에 @EnableRetry를 제공해야 한다는 것을 알게 되었습니다.이 @EnableRetry 주석은 사용자가 재시도하는 메서드를 지정한 클래스 위 또는 메인스프링 부트응용 프로그램클래스 위 중 하나로 할 수 있습니다.예를 들어 다음과 같습니다.
@RequiredArgsConstructor
**@EnableRetry**
@Service
public class SomeService {
**@Retryable(value = { HttpServerErrorException.class, BadRequestException.class},
maxAttempts = maxRetry, backoff = @Backoff(random = true, delay = 1000,
maxDelay = 8000, multiplier = 2))**
public <T> T get( ) throws HttpServerErrorException, BadRequestException {
//write code here which you want to retry
}
}
이것이 당신의 문제를 해결하는 데 도움이 되기를 바랍니다.
@Retryable
재시도하고 싶은 메서드 바로 앞에 있습니다.
여기서부터:
public class MyClass {
public String toBeRetried() {
return delegateTo();
}
@Retryable
public String delegateTo() {
throw new Exception();
}
}
이를 위해:
public class MyClass {
@Retryable
public String toBeRetried() {
throw new Exception();
}
}
언급URL : https://stackoverflow.com/questions/38212471/springboot-retryable-not-retrying
'programing' 카테고리의 다른 글
Android에서 JSON HTTP POST 요청 전송 (0) | 2023.03.23 |
---|---|
jQuery ajax 성공 익명 함수 범위 (0) | 2023.03.23 |
클라이언트 측에서 javascript를 작성하여 'chunked' 응답을 제때 수신하고 해석하는 방법은 무엇입니까? (0) | 2023.03.23 |
WordPress $wpdb를 사용하여 WordPress 데이터베이스의 테이블에 데이터 삽입 (0) | 2023.03.23 |
Wordpress: get_post_field() 함수를 사용하여 게시 내용을 가져올 때 쇼트코드가 작동하지 않습니다. (0) | 2023.03.23 |