我有一个宁静的服务,使用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:连接拒绝在feign.FeignException.errorExecuting(FeignException.java:67)feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:104)feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)假装在feign.FeignException.errorExecuting(FeignException.java:67)执行POST http://external-service/external/payments .ReflectiveFeign $ FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
是否可以在Feign客户端上添加Spring Retry。我想用它来注释addPayment
操作
@Retryable(value = {feign.RetryableException.class }, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier=2))
但这是不可能的,我还有其他选择吗?
你可以在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
示例配置。
如果您使用功能区可以设置属性,则可以使用以下属性进行重试:
myapp.ribbon.MaxAutoRetries=5
myapp.ribbon.MaxAutoRetriesNextServer=5
myapp.ribbon.OkToRetryOnAllOperations=true
注意:“myapp”是您的服务ID。
查看这个Github implementation的工作示例