我尝试这样设置HystrixCommand的行为:
public abstract class AbstractCircuitBreakerCommand<E> extends HystrixCommand<E> {
protected AbstractCircuitBreakerCommand(final String groupKey, final String commandKey) {
this(groupKey, commandKey, TimeUnit.SECONDS, 10, TimeUnit.SECONDS, 3, TimeUnit.SECONDS, 10, 1);
}
protected AbstractCircuitBreakerCommand(
final String groupKey, final String commandKey,
final TimeUnit metricsWindowTimeUnit, final int metricsWindowTime,
final TimeUnit timeoutTimeUnit, final int timeoutTime,
final TimeUnit windowTimeUnit, final int windowTime,
final int threshold) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
.withMetricsRollingStatisticalWindowInMilliseconds((int) metricsWindowTimeUnit.toMillis(metricsWindowTime))
.withExecutionTimeoutEnabled(true)
.withExecutionTimeoutInMilliseconds((int) timeoutTimeUnit.toMillis(timeoutTime))
.withCircuitBreakerEnabled(true)
.withCircuitBreakerRequestVolumeThreshold(threshold)
.withCircuitBreakerErrorThresholdPercentage(0)
.withCircuitBreakerSleepWindowInMilliseconds((int) windowTimeUnit.toMillis(windowTime))
.withFallbackEnabled(true)));
}
}我期望的是在接下来的10秒内只有一个异常(或超时)发生后,短路传入的命令。
为了测试它,我进行了下一个单元测试。
public class AbstractCircuitBreakerCommandTest {
private final static int ERROR_VALUE = Integer.MIN_VALUE;
private final static String GROUP_KEY = "GROUP_KEY";
private final static String COMMAND_KEY = "COMMAND_KEY";
@Test
public void testSimpleExecution() {
final int expectedValue = 1;
final SimpleCircuitBreakerCommandToTest circuitBreakerCommand =
new SimpleCircuitBreakerCommandToTest(GROUP_KEY, COMMAND_KEY, value -> expectedValue);
Assert.assertEquals(expectedValue, (int) circuitBreakerCommand.execute());
Assert.assertTrue(circuitBreakerCommand.isExecutionComplete());
Assert.assertTrue(circuitBreakerCommand.isSuccessfulExecution());
}
@Test
public void testSimpleUnsuccessfulExecutionBecauseException() {
final SimpleCircuitBreakerCommandToTest circuitBreakerCommand =
new SimpleCircuitBreakerCommandToTest(GROUP_KEY, COMMAND_KEY, value -> {
throw new Exception("Test");
});
Assert.assertEquals(ERROR_VALUE, (int) circuitBreakerCommand.execute());
Assert.assertTrue(circuitBreakerCommand.isExecutionComplete());
Assert.assertTrue(circuitBreakerCommand.isFailedExecution());
Assert.assertTrue(circuitBreakerCommand.isCircuitBreakerOpen());
}
@Test
public void testSimpleUnsuccessfulExecutionBecauseTimeout() {
final SimpleCircuitBreakerCommandToTest circuitBreakerCommand =
new SimpleCircuitBreakerCommandToTest(GROUP_KEY, COMMAND_KEY, value -> {
SleepHelper.sleep(TimeUnit.SECONDS, 4); // The default value is -> 3 seconds.
return 1;
});
Assert.assertEquals(ERROR_VALUE, (int) circuitBreakerCommand.execute());
Assert.assertTrue(circuitBreakerCommand.isExecutionComplete());
Assert.assertTrue(circuitBreakerCommand.isFailedExecution());
Assert.assertTrue(circuitBreakerCommand.isCircuitBreakerOpen());
}
private static abstract class AbstractCircuitBreakerCommandToTest extends AbstractCircuitBreakerCommand<Integer> {
private final Integer value;
private final TestAction testAction;
protected AbstractCircuitBreakerCommandToTest(
final String groupKey, final String commandKey,
final TestAction testAction) {
this(groupKey, commandKey, 1, testAction);
}
protected AbstractCircuitBreakerCommandToTest(
final String groupKey, final String commandKey,
final Integer value, final TestAction testAction) {
super(groupKey, commandKey);
this.value = value;
this.testAction = testAction;
}
@Override
protected Integer run() throws Exception {
return this.testAction.run(this.value);
}
@Override
protected Integer getFallback() {
return ERROR_VALUE;
}
@FunctionalInterface
interface TestAction {
Integer run(final Integer integer) throws Exception;
}
}
private static class SimpleCircuitBreakerCommandToTest extends AbstractCircuitBreakerCommandToTest {
protected SimpleCircuitBreakerCommandToTest(
final String groupKey, final String commandKey,
final TestAction testAction) {
super(groupKey, commandKey, testAction);
}
}
} 但是在testSimpleUnsuccessfulExecutionBecauseTimeout和testSimpleUnsuccessfulExecutionBecauseTimeout测试中,isCircuitBreakerOpen()方法返回false。
谁能指引我走正确的路?谢谢。
发布于 2019-01-03 02:26:17
这些测试中有一些错误,这里是修复的版本。
public class AbstractCircuitBreakerCommandTest {
private final static int WAIT_WORK_DONE_IN_MS = 800;
private final static int ERROR_VALUE = Integer.MIN_VALUE;
private final static String GROUP_KEY = "GROUP_KEY";
private final static String COMMAND_KEY = "COMMAND_KEY";
@Test
public void testSimpleExecution() {
final int expectedValue = 1;
final HystrixCommand circuitBreakerCommand =
new SimpleCircuitBreakerCommandToTest(GROUP_KEY + "_0", COMMAND_KEY + "_0", value -> value);
Assert.assertEquals(expectedValue, (int) circuitBreakerCommand.execute());
Assert.assertTrue(circuitBreakerCommand.isExecutionComplete());
Assert.assertTrue(circuitBreakerCommand.isSuccessfulExecution());
}
@Test
public void testSimpleUnsuccessfulExecutionBecauseException() {
final HystrixCommand circuitBreakerCommand =
new SimpleCircuitBreakerCommandToTest(GROUP_KEY + "_1", COMMAND_KEY + "_1", value -> {
throw new Exception("Test");
});
Assert.assertEquals(ERROR_VALUE, (int) circuitBreakerCommand.execute());
SleepHelper.sleep(TimeUnit.MILLISECONDS, WAIT_WORK_DONE_IN_MS);
Assert.assertTrue(circuitBreakerCommand.isExecutionComplete());
Assert.assertTrue(circuitBreakerCommand.isFailedExecution());
Assert.assertTrue(circuitBreakerCommand.isCircuitBreakerOpen());
}
@Test
public void testSimpleUnsuccessfulExecutionBecauseTimeout() {
final HystrixCommand circuitBreakerCommand =
new SimpleCircuitBreakerCommandToTest(GROUP_KEY + "_2", COMMAND_KEY + "_2", value -> {
SleepHelper.sleep(TimeUnit.SECONDS, 4); // The default value is -> 3 seconds.
return value;
});
Assert.assertEquals(ERROR_VALUE, (int) circuitBreakerCommand.execute());
SleepHelper.sleep(TimeUnit.MILLISECONDS, WAIT_WORK_DONE_IN_MS);
Assert.assertTrue(circuitBreakerCommand.isExecutionComplete());
Assert.assertTrue(circuitBreakerCommand.isResponseTimedOut());
Assert.assertTrue(circuitBreakerCommand.isCircuitBreakerOpen());
}
private static abstract class AbstractCircuitBreakerCommandToTest extends AbstractCircuitBreakerCommand<Integer> {
private final Integer value;
private final TestAction testAction;
protected AbstractCircuitBreakerCommandToTest(
final String groupKey, final String commandKey,
final TestAction testAction) {
this(groupKey, commandKey, 1, testAction);
}
protected AbstractCircuitBreakerCommandToTest(
final String groupKey, final String commandKey,
final Integer value, final TestAction testAction) {
super(groupKey, commandKey);
this.value = value;
this.testAction = testAction;
}
@Override
protected Integer run() throws Exception {
return this.testAction.run(this.value);
}
@Override
protected Integer getFallback() {
return ERROR_VALUE;
}
@FunctionalInterface
interface TestAction {
Integer run(final Integer integer) throws Exception;
}
}
private static class SimpleCircuitBreakerCommandToTest extends AbstractCircuitBreakerCommandToTest {
protected SimpleCircuitBreakerCommandToTest(
final String groupKey, final String commandKey,
final TestAction testAction) {
super(groupKey, commandKey, testAction);
}
}
}https://stackoverflow.com/questions/53942421
复制相似问题