Java Hystrix:为命令增加maxSemaphoreCount?

Java Hystrix:为命令增加maxSemaphoreCount?,java,concurrency,hystrix,Java,Concurrency,Hystrix,我对HystrixCommands工作原理的理解是,CommandProperties可以临时更改 然而,当我尝试使用IsolationSemaphoreMaxConcurrentRequests执行此操作时,我对命令配置的更改似乎并没有得到响应 对于已经在同一密钥下指定了配置的Hystrix命令,我是否有能力提供额外配置的错误信息 在Hystrix的上下文中,我是否缺少一些特定于隔离/信号量的东西 下面是我的问题的一个例子。代码首先配置一个允许最多1个信号量的命令,然后将该数量增加到2个信号量

我对
HystrixCommands
工作原理的理解是,
CommandProperties
可以临时更改

然而,当我尝试使用
IsolationSemaphoreMaxConcurrentRequests
执行此操作时,我对命令配置的更改似乎并没有得到响应

对于已经在同一密钥下指定了配置的Hystrix命令,我是否有能力提供额外配置的错误信息

在Hystrix的上下文中,我是否缺少一些特定于隔离/信号量的东西

下面是我的问题的一个例子。代码首先配置一个允许最多1个信号量的命令,然后将该数量增加到2个信号量。此时,它试图利用这两个信号量,但失败了,因为第二个信号量无法获得(我猜是因为允许的最大值仍然是1?)

HystrixCommandKey HystrixCommandKey=HystrixCommandKey.Factory.asKey(“Command1”);
//注意,我们最初将max concurrent requests设置为1
HystrixCommandProperties.Setter maxConcurrentRequests1=HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
.withExecutionTimeoutEnabled(false)
.带有ExecutionIsolationSemaphoreMaxConcurrentRequests(1);
最终HystrixCommand.Setter HystrixCommand Setter=HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(“组”))
.andCommandKey(hystrixCommandKey)
.andCommandPropertiesDefault(maxConcurrentRequests1);
类SleepOneSecond实现了可调用{
@凌驾
公共布尔调用()引发异常{
返回(新HystrixCommand(HYSTRIXCOMMANDSETER){
@凌驾
受保护的布尔运行()引发异常{
睡眠(2_000);
返回true;
}
}).execute();
}
}
ExecutorService线程池=Executors.newFixedThreadPool(2);
threadPool.submit(new sleeptonesecond()).get();
//将命令设置增加到2
hystrixCommandSetter.AndCommandProperties默认值(
maxConcurrentRequests1.withExecutionIsolationSemaphoreMaxConcurrentRequests(2));
//我们现在应该被允许有两个并发命令,因为我们已经将我们的信号量增加到了两个
//这些命令。。。
for(未来结果:threadPool.invokeAll(ImmutableList.of(new SleepOneSecond(),new SleepOneSecond())){
result.get();
//相反,在第二个结果中,我们得到一个:
//com.netflix.hystrix.exception.hystrix运行时异常:Command1无法获取信号量
//用于执行,没有可用的回退。
}

从Github复制的答案问题:

这里的问题是属性应用的粒度。对于每个命令键,该键只有一个属性实例。该键的所有命令都获得该配置。这样做是为了减少操作负担。如果有各种各样的命令实例具有不同的配置(比如超时值),那么这将是一个很难操作、调优和理解的系统


但是,这些值的可调整性也很重要。Hystrix提供Archaius集成,这将允许您在运行时修改信号量计数(或任何其他配置值)。执行此操作时,您正在修改singleton properties实例,并且所有命令都会拾取此值。有关此集成如何工作的更多详细信息,请参阅。

Hey@mattrjacobs,您是否可以提供一个示例,说明在初始执行命令后(通过Archaius集成)如何更新命令的属性?根据您希望利用的技术,有多种方法可以实现此目的。Archaius模型用于轮询配置源。它附带了各种已知的工作配置源,您可以通过实现适当的接口自由添加其他配置源。
HystrixCommandKey hystrixCommandKey = HystrixCommandKey.Factory.asKey("Command1");

// Note that we're initially setting the max concurrent requests to 1
HystrixCommandProperties.Setter maxConcurrentRequests1 = HystrixCommandProperties.Setter()
        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
        .withExecutionTimeoutEnabled(false)
        .withExecutionIsolationSemaphoreMaxConcurrentRequests(1);

final HystrixCommand.Setter hystrixCommandSetter = HystrixCommand.Setter
        .withGroupKey(HystrixCommandGroupKey.Factory.asKey("Group"))
        .andCommandKey(hystrixCommandKey)
        .andCommandPropertiesDefaults(maxConcurrentRequests1);


class SleepOneSecond implements Callable<Boolean> {
    @Override
    public Boolean call() throws Exception {
        return (new HystrixCommand<Boolean>(hystrixCommandSetter) {
            @Override
            protected Boolean run() throws Exception {
                Thread.sleep(2_000);
                return true;
            }
        }).execute();
    }
}

ExecutorService threadPool = Executors.newFixedThreadPool(2);
threadPool.submit(new SleepOneSecond()).get();

// Bumping up the command settings to 2
hystrixCommandSetter.andCommandPropertiesDefaults(
        maxConcurrentRequests1.withExecutionIsolationSemaphoreMaxConcurrentRequests(2));

// We should be allowed to have two concurrent commands now because we've bumped our semaphore cound up to two for
// these commands...
for (Future<Boolean> result :  threadPool.invokeAll(ImmutableList.of(new SleepOneSecond(), new SleepOneSecond()))) {
    result.get();
    // Instead on the second result we end up with a:
    // com.netflix.hystrix.exception.HystrixRuntimeException: Command1 could not acquire a semaphore
    //   for execution and no fallback available.
}