我注意到Hystrix有两种线程隔离策略:Thread和Semaphore。
默认情况下,Hystrix使用线程策略并通过hystrix.threadpool.default.coreSize
控制它,因为具有相同组密钥的caundmand将使用相同的线程池。所以它基于组密钥。
当Hystrix使用信号量策略时,信号量将保存在ConcurrentHashMap
中,键是命令名,是否基于命令名?
以下是代码:
/**
* Get the TryableSemaphore this HystrixCommand should use for execution if not running in a separate thread.
*
* @return TryableSemaphore
*/
protected TryableSemaphore getExecutionSemaphore() {
if (properties.executionIsolationStrategy().get() == ExecutionIsolationStrategy.SEMAPHORE) {
if (executionSemaphoreOverride == null) {
TryableSemaphore _s = executionSemaphorePerCircuit.get(commandKey.name());
if (_s == null) {
// we didn't find one cache so setup
executionSemaphorePerCircuit.putIfAbsent(commandKey.name(), new TryableSemaphoreActual(properties.executionIsolationSemaphoreMaxConcurrentRequests()));
// assign whatever got set (this or another thread)
return executionSemaphorePerCircuit.get(commandKey.name());
} else {
return _s;
}
} else {
return executionSemaphoreOverride;
}
} else {
// return NoOp implementation since we're not using SEMAPHORE isolation
return TryableSemaphoreNoOp.DEFAULT;
}
}
为什么他们的范围不同?我写了一些测试代码来证明它:
public static void main(String[] args) throws InterruptedException {
int i = 0;
while (i++ < 20) {
final int index = i;
new Thread(() -> {
System.out.println(new ThreadIsolationCommand(index).execute());
System.out.println(new SemaphoreIsolationCommand(index).execute());
}).start();
}
}
static class ThreadIsolationCommand extends HystrixCommand<String> {
private int index;
protected ThreadIsolationCommand(int index) {
super(
Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ThreadIsolationCommandGroup"))
.andCommandKey(HystrixCommandKey.Factory.asKey(String.valueOf(index)))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
)
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
.withCoreSize(10)
)
);
this.index = index;
}
@Override
protected String run() throws Exception {
Thread.sleep(500);
return "Hello Thread " + index;
}
@Override
protected String getFallback() {
return "Fallback Thread " + index;
}
}
static class SemaphoreIsolationCommand extends HystrixCommand<String> {
private int index;
protected SemaphoreIsolationCommand(int index) {
super(
Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SemaphoreIsolationCommandGroup"))
.andCommandKey(HystrixCommandKey.Factory.asKey(String.valueOf(index)))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
.withExecutionIsolationSemaphoreMaxConcurrentRequests(10)
)
);
this.index = index;
}
@Override
protected String run() throws Exception {
Thread.sleep(500);
return "Hello Semaphore " + index;
}
@Override
protected String getFallback() {
return "Fallback Semaphore " + index;
}
}
此命令具有相同的组密钥和不同的名称,结果为:
Fallback Thread 9
Fallback Thread 1
Fallback Thread 8
Fallback Thread 19
Fallback Thread 20
Fallback Thread 14
Fallback Thread 3
Fallback Thread 13
Fallback Thread 17
Fallback Thread 10
Hello Thread 5
Hello Semaphore 17
Hello Semaphore 14
Hello Thread 2
Hello Semaphore 3
Hello Thread 7
Hello Thread 15
Hello Thread 4
Hello Semaphore 13
Hello Semaphore 1
Hello Thread 11
Hello Semaphore 20
Hello Semaphore 19
Hello Thread 18
Hello Thread 12
Hello Semaphore 8
Hello Semaphore 9
Hello Thread 6
Hello Thread 16
Hello Semaphore 10
Hello Semaphore 5
Hello Semaphore 2
Hello Semaphore 7
Hello Semaphore 15
Hello Semaphore 4
Hello Semaphore 11
Hello Semaphore 12
Hello Semaphore 6
Hello Semaphore 18
Hello Semaphore 16
只有线程策略失败。是吗?