Hystrix CircuitBreakerSleepWindowInMilliseconds 无法按预期工作

2024-03-14

我正在测试 Hystrix CircuitBreaker 实现。命令类如下所示:

public class CommandOne extends HystrixCommand<String>
{
    private MyExternalService service;    
    public static int runCount = 0;

    public CommandGetPunterUnpayoutExternalBets(MyExternalServoce service)
    {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("AAA"))
                .andThreadPoolPropertiesDefaults(
                        HystrixThreadPoolProperties.Setter().
                         .withMetricsRollingStatisticalWindowInMilliseconds(10000))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withCircuitBreakerEnabled(true)
                        .withCircuitBreakerErrorThresholdPercentage(20)
                        .withCircuitBreakerRequestVolumeThreshold(10)
                        .withExecutionTimeoutInMilliseconds(30)
                        .withCircuitBreakerSleepWindowInMilliseconds(100000)));

        this.service = service;
    }


    @Override
    protected String run()
    {
        run++;
        return service.callMethod();
    }


    @Override
    protected String getFallback()
    {
        return "default;
    }
}

命令的调用方式如下:

public class AnotherClass
{
    private MyExternalServoce service; 

    public String callCmd()
    {
        CommandOne command = new CommandOne(service);
        return command.execute();
    }
}

在测试中我执行以下步骤:

@Test
    public void test()
{
    AnotherClass anotherClass = new AnotherClass();

    // stubbing exception on my service
    when(service.callMethod()).thenThrow(new RuntimeException());
    for (int i = 0; i < 1000; i++)
        {
             anotherClass.callCmd();
        }
    System.out.println("Run method was called times = " + CommandOne.runCount);
}

我对给出的命令配置的期望是:MyExternalService.callMethod() 应该被调用 10 次(RequestVolumeThreshold),之后 100000 毫秒(长时间)不会被调用。在我的测试用例中,我期望 CommandOne.runCount = 10。 但实际上,我收到了 150 到 200 次 MyExternalService.callMethod() 调用(CommandOne.runCount = (150-200)。为什么会发生这种情况?我做错了什么?


根据 Hystrixdocs https://github.com/Netflix/Hystrix/wiki/Configuration#metricshealthsnapshotintervalinmilliseconds健康快照将每 500 毫秒拍摄一次(默认情况下)。这意味着 hystrix 在前 500 毫秒内发生的所有事情都不会影响断路器状态。在你的例子中你得到了随机值runCount因为每次你的机器每 500 毫秒执行随机值的请求,并且只有在该时间间隔之后电路状态才会更新并关闭。

请看一个稍微简化的例子:

 public class CommandOne extends HystrixCommand<String> {

    private String content;
    public static int runCount = 0;


    public CommandOne(String s) {
        super(Setter.withGroupKey
                (HystrixCommandGroupKey.Factory.asKey("SnapshotIntervalTest"))
                .andCommandPropertiesDefaults(
                        HystrixCommandProperties.Setter()
                                .withCircuitBreakerSleepWindowInMilliseconds(500000)
                                .withCircuitBreakerRequestVolumeThreshold(9)
                                .withMetricsHealthSnapshotIntervalInMilliseconds(50)
                                .withMetricsRollingStatisticalWindowInMilliseconds(100000)
                )
        );
        this.content = s;
    }

    @Override
    public String run() throws Exception {
        Thread.sleep(100);
        runCount++;
        if ("".equals(content)) {
            throw new Exception();
        }
        return content;
    }

    @Override
    protected String getFallback() {
        return "FAILURE-" + content;
    }

}

    @Test
    void test() {

        for (int i = 0; i < 100; i++) {
            CommandOne commandOne = new CommandOne();
            commandOne.execute();
        }
        Assertions.assertEquals(10, CommandOne.runCount);
    }

在此示例中我添加了:

  • withMetricsHealthSnapshotIntervalInMilliseconds(50)允许 hystrix 每 50 毫秒拍摄一次快照。
  • Thread.sleep(100);让请求慢一点,如果没有它,它们将快于 50 毫秒,我们将面临最初的问题。

尽管进行了所有这些修改,我还是看到了一些随机失败。之后我得出结论,像这样测试 hystrix 不是一个好主意。我们可以使用:

1) 通过手动设置开路/闭路状态实现回退/成功流程行为 https://stackoverflow.com/questions/29039360/any-samples-to-unit-test-fallback-using-hystrix-spring-cloud#answer-39378236.

2) 配置测试 https://stackoverflow.com/questions/38781398/test-drive-hystrix-circuit-breaker-configuration

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hystrix CircuitBreakerSleepWindowInMilliseconds 无法按预期工作 的相关文章

  • 为什么 JTables 使 TableModel 在呈现时不可序列化?

    所以最近我正在开发一个工具 供我们配置某些应用程序 它不需要是什么真正令人敬畏的东西 只是一个具有一些 SQL 脚本生成功能并创建几个 XML 文件的基本工具 在此期间 我使用自己的 AbstractTableModel 实现创建了一系列
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • 如何使用assertEquals 和 Epsilon 在 JUnit 中断言两个双精度数?

    不推荐使用双打的assertEquals 我发现应该使用带有Epsilon的形式 这是因为双打不可能100 严格 但无论如何我需要比较两个双打 预期结果和实际结果 但我不知道该怎么做 目前我的测试如下 Test public void te
  • 如何在 Spring-JUnit 测试中设置 JNDI 查找?

    我正在使用 Maven 3 0 3 Spring 3 1 0 RELEASE 和 JUnit 4 8 1 如何在容器外部创建 JNDI 功能 在我的例子中是 JBoss 我认为 Spring 的 jndiTemplate 可以解决这个问题
  • 如何获取之前的URL?

    我需要调用我的网络应用程序的 URL 例如 如果有一个从 stackoverflow com 到我的网站 foo com 的链接 我需要 Web 应用程序 托管 bean 中的 stackoverflow 链接 感谢所有帮助 谢谢 并不总是
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • java.lang.IllegalStateException:提交响应后无法调用 sendRedirect()

    这两天我一直在尝试找出问题所在 我在这里读到我应该在代码中添加一个返回 我做到了 但我仍然得到 java lang IllegalStateException Cannot call sendRedirect after the respo
  • 在 junit 测试中获取 javax.lang.model.element.Element 类

    我想测试我的实用程序类 ElementUtils 但我不知道如何将类作为元素获取 在 AnnotationProcessors 中 我使用以下代码获取元素 Set
  • Eclipse Maven Spring 项目 - 错误

    I need help with an error which make me crazy I started to study Java EE and I am going through tutorial on youtube Ever
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • 如何对不同的参数类型使用相同的java方法?

    我的问题 我有 2 个已定义的记录 创建对象请求 更新对象请求 必须通过实用方法进行验证 由于这两个对象具有相同的字段 因此可以对这两种类型应用相同的验证方法 现在我只是使用两种方法进行重载 但它很冗长 public record Crea
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • Cucumber 0.4.3 (cuke4duke) 与 java + maven gem 问题

    我最近开始为 Cucumber 安装一个示例项目 并尝试使用 maven java 运行它 我遵循了这个指南 http www goodercode com wp using cucumber tests with maven and ja
  • 我如何在java中读取二进制数据文件

    因此 我正在为学校做一个项目 我需要读取二进制数据文件并使用它来生成角色的统计数据 例如力量和智慧 它的设置是让前 8 位组成一个统计数据 我想知道执行此操作的实际语法是什么 是不是就像读文本文件一样 这样 File file new Fi
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • 使用反射覆盖最终静态字段是否有限制?

    在我的一些单元测试中 我在最终静态字段上的反射中遇到了奇怪的行为 下面是说明我的问题的示例 我有一个基本的 Singleton 类 其中包含一个 Integer public class BasicHolder private static
  • 如何将双精度/浮点四舍五入为二进制精度?

    我正在编写对浮点数执行计算的代码的测试 不出所料 结果很少是准确的 我想在计算结果和预期结果之间设置一个容差 我已经证实 在实践中 使用双精度 在对最后两位有效小数进行四舍五入后 结果始终是正确的 但是usually四舍五入最后一位小数后
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db

随机推荐