我尝试使用spring retry实现重试机制。然而,重试不起作用。我在主类中添加了@ EnableError annotation
下面是服务类的代码。我想在异常时重试getProductMetadata方法3次。异常是502错误。
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.client.RestTemplate;
@Service
@Slf4j
public class ProductService {
private String productInfoBaseUrl = "http://localhost";
@Value("${service.product.metadata}")
private String productInfoPathProductMetadata;
private static final Logger logger = LoggerFactory.getLogger(ProductService.class);
@Autowired
RestTemplate restTemplate;
int count = 0;
@Retryable(retryFor = Exception.class, maxAttempts = 5, backoff = @Backoff(delay = 100))
public ProductResponse getProductMetadata(String sku, HandlerResult handlerResult) {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
String errorMsg;
String endpoint = getProductFetchMetadataEndpoint();
ResponseEntity<String> response;
try {
response = restTemplate.getForEntity(endpoint, String.class);
} catch (Exception ex) {
errorMsg = "getProductMetadata for sku: " + sku + " threw exception: " + ex.getMessage();
//log.info(errorMsg);
HandlerResult.updateStatus(handlerResult, errorMsg, false);
logger.info(++count + " Call attempts were made");
return null;
}
ProductResponse metadataResponse;
Gson gson = new Gson();
try {
metadataResponse = gson.fromJson(response.getBody(), ProductResponse.class);
} catch (Exception e) {
errorMsg = String.format("Exception ProductResponse converting %s to map", response.getBody());
log.info(errorMsg);
HandlerResult.updateStatus(handlerResult, errorMsg, false);
return null;
}
return metadataResponse;
}
private String getProductFetchMetadataEndpoint() {
return productInfoBaseUrl + "/" + productInfoPathProductMetadata + "/";
}
}
字符串
有人能告诉我我错过了什么吗?
1条答案
按热度按时间wnrlj8wa1#
Spring retry使用一个代理来检测是否抛出了一个可重试的异常,该代理包裹类,寻找抛出异常的方法调用。
如果你在方法中捕捉到所有的异常,那么代理将不会看到任何异常,也不会知道它需要重试任何东西。
您仍然可以捕获异常,用于日志记录等目的,只要确保重新抛出您想要重试的任何内容即可。
Here是我发布的另一个使用spring retry的工作示例的答案。从retryable方法中抛出并触发重试行为。