如何解决如何使用 Resilience4j 断路器装饰外部依赖中的服务方法特别是在 Spring Cloud 配置服务器上?
如何使用 Resilience4j 断路器装饰外部库中的服务方法?具体来说,我想在 spring 云配置服务器(服务器本身,而不是客户端代码)中装饰一个方法:org.springframework.cloud.config.server.environment.EnvironmentController.labelled(...)
。它需要多个参数。我无法对其进行注释,因为它位于第 3 方库中。
EnvironmentController
类是 Spring @RestController
。
我在 CircuitBreaker
中看到了用于装饰 Callables、Functions 等的方法,但似乎没有一个方法适用于此。 (我对 Resilience4j 完全陌生,所以我希望我错过了一个简单的解决方案。)
解决方法
一种常见的方法(不仅是 Resilience4j
,而且是一般的 Spring
)是使用 BeanPostProcessor
(你可以看到一个不相关的例子 here ).
然后在 beanPostProcessor 中,您可以获得 EnvironmentController
的句柄,并使用 Resilience4j
CicrcuitBreaking 逻辑环绕其实现/方法。
基本上该方法类似于:
- 在您的
BeanPostProcessor
中使用@Configuration
来处理完全连接的EnvironmentController
- 使用 Resilience4j 围绕您感兴趣的
CircuitBreaker
方法包装您自己的EnvirommentController
实现 - 利润
如果这不能完全清除图片,我可以添加一些示例代码来帮助您入门,请告诉我。请记住,这可能只是解决此问题的众多方法之一。
编辑:
一些代码(不确定它是否有效,还没有测试,spring-boot
在为 MVC 映射自动配置使用大量 aop
方面是出了名的烦人,所以你可能不得不使用方面或代理配置代替),可能看起来像(请记住,为了后代,我会使用 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 label) {
return circuitBreaker.executeSupplier(() -> {
log.info("such wow");
return environmentController.labelled(name,profiles,label);
});
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。