当前位置: 首页 > 知识库问答 >
问题:

带断路器的Spring重试

苗信鸥
2023-03-14

我试图利用Spring重试的重试和断路器机制。我试图在一个特定的函数中使用两个注释(@retryable和@circuitbreaker),但是Circuit Breaker不起作用。

@Service
public class CommandAndRetry {

    private static final Logger LOGGER = LoggerFactory.getLogger(SampleRetryService.class);

    @CircuitBreaker(maxAttempts = 1, openTimeout = 10000)
    @Retryable(
            value = {TypeOneException.class},
            maxAttempts = 3, backoff = @Backoff(2000))
    public void retryWhenException() throws TypeOneException {
        LOGGER.info("Retrying");
        throw new TypeOneException();
    }

    @Recover
    public void recover(Throwable t) throws Throwable {
        LOGGER.info("SampleRetryService.recover");
        throw t;
    }
}
@Service
public class CommandAndRetry {

    private static final Logger LOGGER = LoggerFactory.getLogger(SampleRetryService.class);


    @CircuitBreaker(maxAttempts = 1, openTimeout = 10000)
    public void exec() throws TypeOneException {
        retryWhenException();
    }

    @Retryable(
            value = {TypeOneException.class},
            maxAttempts = 3, backoff = @Backoff(2000))
    public void retryWhenException() throws TypeOneException {
        LOGGER.info("Retrying");
        throw new TypeOneException();
    }

    @Recover
    public void recover(Throwable t) throws Throwable {
        LOGGER.info("SampleRetryService.recover");
        throw t;
    }
}

另外,请告知是否有更好的方法来实现重试和断路器。PS:我既不想使用resilience4j也不想使用RetryTemplate。

共有1个答案

潘翊歌
2023-03-14

如果你想在断路器内重试,它们必须在不同的豆子里。如果在同一个bean中直接从另一个@retryable调用一个,则将绕过拦截器。

对我来说很好...

@SpringBootApplication
@EnableRetry
public class So52193237Application {

    public static void main(String[] args) {
        SpringApplication.run(So52193237Application.class, args);
    }

    @Bean
    public ApplicationRunner runner(Foo foo) {
        return args -> {
            try {
                foo.exec();
            }
            catch (Exception e) {
                try {
                    foo.exec();
                }
                catch (Exception ee) {
                    Thread.sleep(11000);
                    try {
                        foo.exec();
                    }
                    catch (Exception eee) {

                    }
                }
            }
        };
    }

    @Component
    public static class Foo {

        private static final Logger LOGGER = LoggerFactory.getLogger(Foo.class);

        private final Bar bar;

        public Foo(Bar bar) {
            this.bar = bar;
        }

        @CircuitBreaker(maxAttempts = 1, openTimeout = 10000, resetTimeout=10000)
        public void exec() throws TypeOneException {
            LOGGER.info("Foo.circuit");
            this.bar.retryWhenException();
        }

        @Recover
        public void recover(Throwable t) throws Throwable {
            LOGGER.info("Foo.recover");
            throw t;
        }

    }

    @Component
    public static class Bar {

        private static final Logger LOGGER = LoggerFactory.getLogger(Bar.class);

        @Retryable(value = { TypeOneException.class }, maxAttempts = 3, backoff = @Backoff(2000))
        public void retryWhenException() throws TypeOneException {
            LOGGER.info("Retrying");
            throw new TypeOneException();
        }

        @Recover
        public void recover(Throwable t) throws Throwable {
            LOGGER.info("Bar.recover");
            throw t;
        }

    }

}

 类似资料:
  • 我正在尝试春云和春靴。它使用了Netflix的OSS应用程序,其中有Ribbon和Hystrix。 Ribbon是一个负载均衡器,带有一些功能,其中一个是断路器。

  • 我需要一些帮助来理解我如何能够提出一个解决方案使用Spring boot、Kafka、Resilence4J来实现来自我的Kafka消费者的微服务调用。假设微服务关闭了,那么我需要使用断路器模式通知我的Kafka消费者停止获取消息/事件,直到微服务启动并运行。

  • 注:本节未经校验,如有问题欢迎提issue 为什么使用它们? 线路断路器用于提供稳定性并防止在分布式系统中的级联故障。它们应该结合在远程系统之间的接口使用明智的超时,以防止单个组件的故障拖垮所有组件。 作为一个例子,我们有一个web 应用程序与远程的第三方web服务进行交互。假如第三方已用完了他们的容量,他们的数据库也在高荷载作用下熔化。假设数据库在这种情况下失败,第三方 web 服务用了很长的时

  • 我需要在1.3.0版本的Spring启动应用程序中使用Spring重试和Spring断路器。Spring重试版本捆绑了此版本的Spring启动,即1.3.0版本不支持断路器。如果我使用Spring重试最新版本与Spring启动1.3.0版本,可以吗?它会导致任何运行时问题吗?

  • 我想用Resilience4j来处理容错,我用的是断路器和定时器限制。 我想分离业务逻辑的容错行为,不要“弄脏”我的业务代码。 2-我如何有这个应用程序的许多实例,断路器为每个实例单独工作?我是对的?

  • 断路器将处于闭合或半断开状态无限时间,直到达到最小的呼叫次数,对吗?有什么办法我可以设置什么时候没有调用在数量的时间,它将转为关闭状态?另外,在半开状态下,是否有可能使最小呼叫数大于允许的呼叫数?谢谢。