当前位置: 首页 > 后端技术 > Java

【翻译】如何自定义feign的重试机制

时间:2023-04-01 14:04:35 Java

在微服务框架中,通过restapi调用其他服务是正常的。在spring生态系统中,一个流行的REST客户端是Feign,因为它有著名的风格和添加不同配置的DRY方式。在这篇博客中,我将讨论feignclient的重试机制。本能地,我们会这样实现,把api调用语句写在trycatch和while循环中,再写一次api调用的代码,直到满足条件。这可能符合我们的目的,但它会使我们的代码变得丑陋且无法实现。理想情况下,一切正常,我们不需要重试任何HTTP请求。所以feign中默认是不开启retry的。话又说回来,完美是不存在的,网络中有数百万种让tcp数据包死亡的方法。因此,为了启用重试,您必须将以下代码放入客户端配置中。@BeanpublicRetryerretryer(){returnnewRetryer.Default();}可以在default方法中传入一些参数,比如:间隔时间,最大重试次数等,否则会重试5次,间隔为1秒。这只是让遇到IO异常时feign重试。这有点道理,对吧?仅当Y不可访问时,X才应重试获取Y。但这并不经常发生。Y返回5XX错误码可能是因为Y和Z之间的连接断开了,此时你想重试。要使用它,您必须抛出RetryableException。为了达到这个目的,我们需要实现ErrorDecoder类。代码如下所示:publicclassMyErrorDecoderimplementsErrorDecoder{@OverridepublicExceptiondecode(Strings,Responseresponse){异常异常=defaultErrorDecoder.decode(s,responseofExceptionReponse);inst(){返回异常;}if(response.status()==504){returnnewRetryableException("504error",response.request().httpMethod(),null);}返回异常;}}为了让上面的代码生效,你必须在应用程序属性文件中加入如下配置:让我们看看MyErrorDecoder类做了什么。它实现了ErrorDecoder类并覆盖了它的decode方法,这是显而易见的。在decode方法中,首先我们检查抛出的异常是否已经是RetryableException。如果已经是RetryableException,那么这是feign自己抛出的异常,如果我们返回这个异常,feign会自己重试。如果异常不是RetryableException,将执行第二个代码块。在这段代码中,我们检查返回的状态是否为504。如果是,我们手动返回RetryableException。我们可以在errorDecoder中做很多事情。想象一下您想要重试任何5XX错误代码的场景,无论这是否是您的实际场景。那我们该怎么办呢?写一堆if/else?不,你不需要,你只需要:;下面也是一种自定义重试机制的方法。你为什么做这个?在我的场景中,当每次重试发生时,我首先打印日志。为了自定义这个重试器,首先删除配置中的默认重试器。然后像这样创建一个模块:@Slf4j@Component@NoArgsConstructorpublicclassCustomRetryerimplementsRetryer{privateintretryMaxAttempt;私人长重试间隔;私人尝试=1;publicCustomRetryer(intretryMaxAttempt,LongretryInterval){this.retryMaxAttempt=retry.retryInterval=retryInterval;}@OverridepublicvoidcontinueOrPropagate(RetryableExceptione){log.info("Feignretryattempt{}dueto{}",attempt,e.getMessage());if(attempt++==retryMaxAttempt){抛出e;}尝试{线程。睡眠(重试间隔);}catch(忽略中断异常){线程。当前线程()。打断();}}@OverridepublicRetryerclone(){returnnewCustomRetryer(6,2000L);这里我们的CustomRetryer覆盖了continueOrPropagate和clone方法,它们是feign的默认重试器方法。在clone方法中,我们创建一个带有所需参数的CustomRetryer,其中6为最大重试次数,每次重试的间隔为2000L。在continueOrPropagate方法中,您可以自定义重试机制。请记住,为了停止重试和传播错误消息,您必须抛出此方法收到的可重试异常。否则,它会不断重试。在此示例中,我们在尝试最大重试次数后抛出此异常,否则它会等待间隔(参数),然后再进行下一次重试。到目前为止,我们所看到的是如何创建自定义错误解码器和重发器,以将feign的可靠性扩展到我们的需求。如果您以这种方式创建错误解码器和重试器,它将适用于您添加到项目中的任意数量的假客户端。但是,想象一下这样一种场景,您希望针对不同的客户端使用不同的重试机制,或者不对其他客户端进行重试。你打算做什么将无法访问的重试器和编码器绑定到无法访问的客户端非常容易。只需像这样配置它:feign.client.config.default..error-decoder=com.example.somepackage.MyErrorDecoderfeign.client.config.client1.retryer=com.example.somepackage.CustomRetryer重试快乐!!原文地址:https://medium.com/swlh/how-t...