我有一个宁静的服务,使用Spring Cloud Feign客户端调用外部服务
@FeignClient(name = "external-service", configuration = FeignClientConfig.class) public interface ServiceClient { @RequestMapping(value = "/test/payments", method = RequestMethod.POST) public void addPayment(@Valid @RequestBody AddPaymentRequest addPaymentRequest); @RequestMapping(value = "/test/payments/{paymentId}", method = RequestMethod.PUT) public ChangePaymentStatusResponse updatePaymentStatus(@PathVariable("paymentId") String paymentId, @Valid @RequestBody PaymentStatusUpdateRequest paymentStatusUpdateRequest); }
最近3个月,我在日志文件中发现3-4次以下失败:
json.ERROR_RESPONSE_BODY:连接拒绝执行POST http:// external-service / external / payments json.message:发送付款添加付款失败出于其他原因:{ERROR_RESPONSE_BODY =连接拒绝执行POST http:// external-service / external / payments,EVENT = ADD_PAYMENT_FAILURE,TRANSACTION_ID = XXXXXXX} {} json.EVENT:ADD_PAYMENT_FAILURE json.stack_trace:feign.RetryableException:连接拒绝执行POST http:// external- service / external / payments 在feign.FeignException.errorExecuting(FeignException.java:67)在feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:104)在feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)在feign.ReflectiveFeign $ FeignInvocationHandler.invoke(Reflective) Java:103)
是否可以在Feign客户端上添加Spring Retry。我想用什么来注释addPayment操作
addPayment
@Retryable(value = {feign.RetryableException.class }, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier=2))
但这是不可能的,我还有什么其他选择?
您可以添加Retryer在FeignClientConfig
Retryer
FeignClientConfig
@Configuration public class FeignClientConfig { @Bean public Retryer retryer() { return new Custom(); } } class Custom implements Retryer { private final int maxAttempts; private final long backoff; int attempt; public Custom() { this(2000, 3); } public Custom(long backoff, int maxAttempts) { this.backoff = backoff; this.maxAttempts = maxAttempts; this.attempt = 1; } public void continueOrPropagate(RetryableException e) { if (attempt++ >= maxAttempts) { throw e; } try { Thread.sleep(backoff); } catch (InterruptedException ignored) { Thread.currentThread().interrupt(); } } @Override public Retryer clone() { return new Custom(backoff, maxAttempts); } }
更新了Retryer基于的示例示例配置Retryer.Default。
Retryer.Default