微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用注释正确配置弹性 4J 回退客户端?

如何解决如何使用注释正确配置弹性 4J 回退客户端?

正如标题所暗示的,下面是一个根据 YAML 配置挂钩到 Euereka 注册表的类,并查找不存在的客户端 fallback-test URL。

@FeignClient(name = "fallback-test",configuration = TestFallbackClientLoggingConfiguration.class)
public interface TestFallbackClient {

    @RequestMapping(method = RequestMethod.GET,path = "/fall-back-not-found-data")
    @CircuitBreaker(name = "fall-back-not-found",fallbackMethod = "getFallbackbrokenCircuit")
    String getFallbackData(@RequestParam(value = "uid") String uid);

    default String getFallbackbrokenCircuit(String uid,Throwable cause) {
        if (cause instanceof FeignException) {
            return "Could NOT GET FALL BACK DATA";
        } else {
            return cause.toString();
        }
    }
}

@Configuration
class TestFallbackClientLoggingConfiguration {

    @Bean
    Logger.Level feignTestFallbackClientLoggerLevel() {
        return Logger.Level.BASIC;
    }
}

这是单元测试,据我所知,它应该可以工作,或者更确切地说是表明了我的意图。

@SpringBoottest
@ExtendWith(SpringExtension.class)
class TestFallbackClientTest {

    @Autowired
    private TestFallbackClient testFallbackClient;

    @Test
    @displayName("Test fall back client implementation")
    public void test_fall_back_client_gives_fallback_text() {
        String data = testFallbackClient.getFallbackData("some_invalid_data");
        assertEquals("Could NOT GET FALL BACK DATA",data);
    }
}

由于 URL 不存在,我希望 Eureka 给我一个 503 或类似的错误,从而为我提供后备认文本 Could NOT GET FALL BACK DATA

但是,这是我在应用程序启动时遇到的错误

java.lang.IllegalStateException: Failed to load ApplicationContext

  at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
  at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124)
  at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
  at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
  at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
  at org.springframework.test.context.junit.jupiter.SpringExtension.postProcesstestInstance(SpringExtension.java:138)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$6(ClassBasedTestDescriptor.java:350)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:355)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$7(ClassBasedTestDescriptor.java:350)
  at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
  at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
  at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
  at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
  at java.base/java.util.stream.AbstractPipeline.wrapAndcopyInto(AbstractPipeline.java:474)
  at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
  at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
  at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
  at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:349)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcesstestInstance$4(ClassBasedTestDescriptor.java:270)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcesstestInstance(ClassBasedTestDescriptor.java:269)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$2(ClassBasedTestDescriptor.java:259)
  at java.base/java.util.Optional.orElseGet(Optional.java:362)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$3(ClassBasedTestDescriptor.java:258)
  at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:101)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:100)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:65)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:111)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:111)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:79)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
  at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
  at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
  at org.junit.platform.launcher.core.EngineExecutionorchestrator.execute(EngineExecutionorchestrator.java:108)
  at org.junit.platform.launcher.core.EngineExecutionorchestrator.execute(EngineExecutionorchestrator.java:88)
  at org.junit.platform.launcher.core.EngineExecutionorchestrator.lambda$execute$0(EngineExecutionorchestrator.java:54)
  at org.junit.platform.launcher.core.EngineExecutionorchestrator.withInterceptedStreams(EngineExecutionorchestrator.java:67)
  at org.junit.platform.launcher.core.EngineExecutionorchestrator.execute(EngineExecutionorchestrator.java:52)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
  at com.intellij.junit5.junit5IdeaTestRunner.startRunnerWithArgs(junit5IdeaTestRunner.java:71)
  at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
  at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
  at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.IllegalStateException: Error processing condition on io.github.resilience4j.retry.autoconfigure.AbstractRetryConfigurationOnMissingBean.retryRegistry
  at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60)
  at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108)
  at org.springframework.context.annotation.ConfigurationClassBeanDeFinitionReader.loadBeanDeFinitionsForBeanMethod(ConfigurationClassBeanDeFinitionReader.java:193)
  at org.springframework.context.annotation.ConfigurationClassBeanDeFinitionReader.loadBeanDeFinitionsForConfigurationClass(ConfigurationClassBeanDeFinitionReader.java:153)
  at org.springframework.context.annotation.ConfigurationClassBeanDeFinitionReader.loadBeanDeFinitions(ConfigurationClassBeanDeFinitionReader.java:129)
  at org.springframework.context.annotation.ConfigurationClasspostProcessor.processConfigBeanDeFinitions(ConfigurationClasspostProcessor.java:343)
  at org.springframework.context.annotation.ConfigurationClasspostProcessor.postProcessBeanDeFinitionRegistry(ConfigurationClasspostProcessor.java:247)
  at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDeFinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311)
  at org.springframework.context.support.PostProcessorRegistrationDelegate.invokebeanfactoryPostProcessors(PostProcessorRegistrationDelegate.java:112)
  at org.springframework.context.support.AbstractApplicationContext.invokebeanfactoryPostProcessors(AbstractApplicationContext.java:746)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769)
  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
  at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:326)
  at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:123)
  at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
  at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
  ... 67 more
Caused by: java.lang.IllegalStateException: Failed to introspect Class [io.github.resilience4j.retry.autoconfigure.AbstractRetryConfigurationOnMissingBean] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@3d4eac69]
  at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481)
  at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:358)
  at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:371)
  at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:414)
  at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.lambda$getTypeForFactoryMethod$2(AbstractAutowireCapablebeanfactory.java:747)
  at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
  at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.getTypeForFactoryMethod(AbstractAutowireCapablebeanfactory.java:746)
  at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.determinetargettype(AbstractAutowireCapablebeanfactory.java:685)
  at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.predictBeanType(AbstractAutowireCapablebeanfactory.java:656)
  at org.springframework.beans.factory.support.Abstractbeanfactory.isfactorybean(Abstractbeanfactory.java:1670)
  at org.springframework.beans.factory.support.DefaultListablebeanfactory.doGetBeanNamesForType(DefaultListablebeanfactory.java:570)
  at org.springframework.beans.factory.support.DefaultListablebeanfactory.getBeanNamesForType(DefaultListablebeanfactory.java:542)
  at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:238)
  at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:231)
  at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:221)
  at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:169)
  at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:144)
  at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
  ... 84 more
Caused by: java.lang.NoClassDefFoundError: io/github/resilience4j/core/ContextAwareScheduledThreadPoolExecutor
  at java.base/java.lang.class.getDeclaredMethods0(Native Method)
  at java.base/java.lang.class.privateGetDeclaredMethods(Class.java:3244)
  at java.base/java.lang.class.getDeclaredMethods(Class.java:2387)
  at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463)
  ... 101 more
Caused by: java.lang.classNotFoundException: io.github.resilience4j.core.ContextAwareScheduledThreadPoolExecutor
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
  at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
  at java.base/java.lang.classLoader.loadClass(ClassLoader.java:522)
  ... 105 more

我目前不清楚如何使用 resilience-4j 库。 open feign https://resilience4j.readme.io/docs/feign 的参考页面有 feign 装饰器的例子,但是我如何使用它们并将它们连接到 feign 类。在浏览该页面上的代码示例时,它似乎完全忽略了装饰器。

为了让事情顺利进行,我只是把厨房的水槽扔了,并根据文档将其包含在 YAML 中

resilience4j.circuitbreaker:
  configs:
    default:
      registerHealthindicator: true
      slidingWindowSize: 10
      minimumNumberOfCalls: 5
      permittednumberOfCallsInHalfOpenState: 3
      automaticTransitionFromOpenToHalfOpenEnabled: true
      waitDurationInopenState: 5s
      failureRateThreshold: 50
      eventConsumerBufferSize: 10
      recordExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.util.concurrent.TimeoutException
        - java.io.IOException
      ignoreExceptions:
        - io.github.robwin.exception.BusinessException

resilience4j.retry:
  configs:
    default:
      maxRetryAttempts: 3
      waitDuration: 100
      retryExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.util.concurrent.TimeoutException
        - java.io.IOException
      ignoreExceptions:
        - io.github.robwin.exception.BusinessException

但即便如此也无济于事。图书馆说,你可以挑选,所以我很确定我的用例只有一个回退客户端给我空,我如何用最少的配置来配置它。

我真的必须创建所有单独的配置类,例如隔板、重试和断路器吗?这似乎与图书馆的目标背道而驰。

感谢任何帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。