伪造客户端和Spring重试

ktecyv1j  于 2023-04-28  发布在  Spring
关注(0)|答案(7)|浏览(124)

我有一个使用Spring Cloud Feign客户端调用外部服务的REST服务

@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:Connection refused executing 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。事件:ADD_PAYMENT_FAILURE json。stack_trace:feign.RetryableException:连接拒绝执行POST http://external-service/external/payments(在假装时)。FeignException。errorExecuting(FeignException.java:67)at fign.SynchronousMethodHandler。executeAndDecode(SynchronousMethodHandler.java:104)at feign.SynchronousMethodHandler。invoke(SynchronousMethodHandler.java:76)at feign.ReflectiveFeign$FeignInvocationHandler。invoke(ReflectiveFeign.java:103)
是否可以在Feign客户端上添加Spring重试。我想用什么来注解addPayment操作

@Retryable(value = {feign.RetryableException.class }, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier=2))

但这是不可能的,我还有其他选择吗?

nxagd54h

nxagd54h1#

您可以在FeignClientConfig中添加Retryer

@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.DefaultRetryer示例配置进行了更新。

ar5n3qh5

ar5n3qh52#

如果使用功能区,则可以设置属性,可以使用以下属性进行重试:

myapp.ribbon.MaxAutoRetries=5
myapp.ribbon.MaxAutoRetriesNextServer=5
myapp.ribbon.OkToRetryOnAllOperations=true

注意:“myapp”是您的服务ID。
查看此Github implementation以获取工作示例

roqulrg3

roqulrg33#

只是新的一个constructor Default

@Configuration
public class FeignClientConfig {
    @Bean
    public Retryer retryer() {
        return new Retryer.Default(100, 2000, 3);
    }
}
svgewumm

svgewumm4#

如果能帮到人的话就加上这个。我正在使用feign重置连接,因为一些未知的进程正在该端口上运行。尝试更改端口。Refer this to find the process running on a port

evrscar2

evrscar25#

我准备了一篇关于使用Spring Retry与Feign Client方法的博客文章。您可以考虑检查Post。所有步骤都在帖子中解释过了。

oxcyiej7

oxcyiej76#

这是我的配置。在 Spring Boot 2中测试正常。2.0.RELEASESpring Cloud霍克斯顿。M3

feign.hystrix.enabled=true
MY-SPRING-API.ribbon.MaxAutoRetries=2
MY-SPRING-API.ribbon.MaxAutoRetriesNextServer=2
MY-SPRING-API.ribbon.OkToRetryOnAllOperations=true
MY-SPRING-API.ribbon.retryableStatusCodes=404,500

feign.client.config.PythonPatentClient.connectTimeout=500
feign.client.config.PythonPatentClient.readTimeout=500

hystrix.command.PythonPatentClient#timeTest(String).execution.isolation.thread.timeoutInMilliseconds=5000

java代码是:

@FeignClient(name = "MY-SPRING-API",configuration = {PythonPatentConfig.class},fallbackFactory = FallBack.class)
public interface PythonPatentClient 
@RequestLine("GET /test?q={q}")
    void timeTest(@Param("appNo") String q);

控制器为:

@RequestMapping(value = "/test",method = {RequestMethod.POST,RequestMethod.GET})
    public Object test() throws InterruptedException {
        log.info("========important print enter test========");
         TimeUnit.SECONDS.sleep(10L);

pom.xml additon add:

<dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
   </dependency>

可选:

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
    </dependency>

@EnableRetry
@SpringBootApplication
public class ApiApplication

这是文件:
www.example. com
https://github.com/spring-projects/spring-retry
https://github.com/spring-cloud/spring-cloud-netflix/

kt06eoxx

kt06eoxx7#

我通过在ServiceClient之上创建一个 Package 器解决了这个问题

@Configuration
public class ServiceClient {

@Autowired
ServiceFeignClient serviceFeignClient;

@Retryable(value = { ClientReprocessException.class }, maxAttemptsExpression = "#{${retryMaxAttempts}}", backoff = @Backoff(delayExpression = "#{${retryDelayTime}}"))

public void addPayment( AddPaymentRequest addPaymentRequest){
    return serviceFeignClient.addPayment(addPaymentRequest);
 }    
}

相关问题