Spring @Retryable注解在Sping Boot 应用程序中不起作用

q1qsirdb  于 2024-01-05  发布在  Spring
关注(0)|答案(1)|浏览(187)

我尝试使用spring retry实现重试机制。然而,重试不起作用。我在主类中添加了@ EnableError annotation
下面是服务类的代码。我想在异常时重试getProductMetadata方法3次。异常是502错误。

  1. import com.google.gson.Gson;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.http.HttpHeaders;
  7. import org.springframework.http.HttpStatus;
  8. import org.springframework.http.ResponseEntity;
  9. import org.springframework.retry.annotation.Backoff;
  10. import org.springframework.retry.annotation.EnableRetry;
  11. import org.springframework.retry.annotation.Recover;
  12. import org.springframework.retry.annotation.Retryable;
  13. import org.springframework.stereotype.Service;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.springframework.web.client.RestTemplate;
  16. @Service
  17. @Slf4j
  18. public class ProductService {
  19. private String productInfoBaseUrl = "http://localhost";
  20. @Value("${service.product.metadata}")
  21. private String productInfoPathProductMetadata;
  22. private static final Logger logger = LoggerFactory.getLogger(ProductService.class);
  23. @Autowired
  24. RestTemplate restTemplate;
  25. int count = 0;
  26. @Retryable(retryFor = Exception.class, maxAttempts = 5, backoff = @Backoff(delay = 100))
  27. public ProductResponse getProductMetadata(String sku, HandlerResult handlerResult) {
  28. HttpHeaders headers = new HttpHeaders();
  29. headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
  30. String errorMsg;
  31. String endpoint = getProductFetchMetadataEndpoint();
  32. ResponseEntity<String> response;
  33. try {
  34. response = restTemplate.getForEntity(endpoint, String.class);
  35. } catch (Exception ex) {
  36. errorMsg = "getProductMetadata for sku: " + sku + " threw exception: " + ex.getMessage();
  37. //log.info(errorMsg);
  38. HandlerResult.updateStatus(handlerResult, errorMsg, false);
  39. logger.info(++count + " Call attempts were made");
  40. return null;
  41. }
  42. ProductResponse metadataResponse;
  43. Gson gson = new Gson();
  44. try {
  45. metadataResponse = gson.fromJson(response.getBody(), ProductResponse.class);
  46. } catch (Exception e) {
  47. errorMsg = String.format("Exception ProductResponse converting %s to map", response.getBody());
  48. log.info(errorMsg);
  49. HandlerResult.updateStatus(handlerResult, errorMsg, false);
  50. return null;
  51. }
  52. return metadataResponse;
  53. }
  54. private String getProductFetchMetadataEndpoint() {
  55. return productInfoBaseUrl + "/" + productInfoPathProductMetadata + "/";
  56. }
  57. }

字符串
有人能告诉我我错过了什么吗?

wnrlj8wa

wnrlj8wa1#

Spring retry使用一个代理来检测是否抛出了一个可重试的异常,该代理包裹类,寻找抛出异常的方法调用。
如果你在方法中捕捉到所有的异常,那么代理将不会看到任何异常,也不会知道它需要重试任何东西。
您仍然可以捕获异常,用于日志记录等目的,只要确保重新抛出您想要重试的任何内容即可。
Here是我发布的另一个使用spring retry的工作示例的答案。从retryable方法中抛出并触发重试行为。

相关问题