1

如何使用 Resilience4j 断路器在外部库中装饰服务方法?具体来说,我想在spring cloud config server(服务器本身,而不是客户端代码)中装饰一个方法:org.springframework.cloud.config.server.environment.EnvironmentController.labelled(...). 它需要多个参数。我无法注释它,因为它在第 3 方库中。

EnvironmentController类是一个 Spring @RestController

我看到了CircuitBreaker用于装饰 Callables、Functions 等的方法,但似乎没有一个适用于此。(我对 Resilience4j 完全陌生,所以我希望我错过了一个简单的解决方案。)

4

1 回答 1

1

一种常见的方法(不仅是Resilience4j,而且Spring一般而言)是使用 a (您可以在此处BeanPostProcessor看到一个不相关的示例)。

然后在 beanPostProcessor 中,您可以获取您的句柄并使用您的CicrcuitBreaking 逻辑EnvironmentController环绕它的实现/方法。Resilience4j

基本上,该方法将类似于:

  • 使用 aBeanPostProcessor@Configuration获得完全接线的手柄EnvironmentController
  • CircuitBreaker使用 Resilience4j 围绕EnvirommentController您感兴趣的方法包装您自己的实现
  • 利润

如果这不能完全清除图片,我可以添加一些示例代码来帮助您入门,请告诉我。请记住,这可能只是可以解决的众多方法之一。

编辑:

一些代码(不确定它是否有效,尚未测试,spring-boot在使用大量aop的 MVC 映射自动配置方面非常烦人,因此您可能不得不使用方面或代理配置),可能看起来像(请记住,为了后代,我会使用 lombok 来避免所有样板):

@Configuration
@Slf4j
public class MyConfig {

    // or however the heck you get your breaker config
    private final CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom().build();
    private final CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(circuitBreakerConfig);
    private final CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker("suchBreakerMuchWow");

    @Bean
    public CircuitBreakerAwarePostProcessor circuitBreakerAwarePostProcessor() {
        return new CircuitBreakerAwarePostProcessor();
    }

    public class CircuitBreakerAwarePostProcessor implements BeanPostProcessor {

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof EnvironmentController) {
                return new CircuitBreakerFriendlyEnvironmentController((EnvironmentController) bean);
            }
            return bean;
        }
    }

    private interface Exclude {
        Environment labelled (String name, String profiles, String label);
    }

    @RequiredArgsConstructor
    private class CircuitBreakerFriendlyEnvironmentController implements Exclude {

        @Delegate(types = EnvironmentController.class, excludes = Exclude.class)
        @NonNull private final EnvironmentController environmentController;

        @Override
        public Environment labelled(String name, String profiles, String label) {
            return circuitBreaker.executeSupplier(() -> {
                log.info("such wow");
                return environmentController.labelled(name, profiles, label);
            });
        }
    }
}
于 2021-07-07T19:25:17.657 回答