HystrixCommand 的奇怪行为
strange behavior of HystrixCommand
该项目使用 SpringBoot(2.3.4)
和 SpringCloud(Hoxton.SR8)
。
一共有三个类:BillController、BillService(接口)和BillServiceImpl(实现BillService),BillController调用BillService中声明的函数getBillList
。
BillServiceImpl中有两种方法,一种是getBillList
,另一种是simulateUnstableService
,getBillList
调用simulateUnstableService
,而在simulateUnstableService
中只是长眠(2000).
奇怪的是,如果我用 HystrixCommand
注释 getBillList
,那么它会像我预期的那样工作。但是如果我移动 HystrixCommand
来注释 simulateUnstableService
,那么就没有中断,这意味着超时不会触发 Circuit Breaker
。
@Service
public class BillServiceImpl implements BillService {
@Override
// have effact
@HystrixCommand(
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
}
)
public List<Bill> getBillList(long userId) {
return simulateUnstableService(userId);
}
// no effact
// @HystrixCommand(
// commandProperties = {
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
// }
// )
public List<Bill> simulateUnstableService(long userId) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new ArrayList<>();
}
}
此外,如果我只是将 simulateUnstableService
方法内容复制到 getBillList
,并使用 HystrixCommand 注释 getBillList,断路器也可以工作。
为什么?
当电路中断时调用回退方法。我们需要在 hystrix 命令中提及 fallback 方法。回退方法与 hystrix 注释的方法具有相同的签名。
simulateUnstableService 是你的后备方法吗?
@HystrixCommand(fallbackMethod='yourFallbackMethod'
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
}
)
public List<Bill> getBillList(long userId) {
return simulateUnstableService(userId);
}
此外,最好在 application.properties 文件中添加 hystrix 命令属性,而不是随注释一起提供。
问得好。
Hystrix 使用 AOP 包装被调用的方法并提供 Circuit Braking 功能。实际上有一个方面 class HystrixCommandAspect.java
定义了用于实现此目的的环绕建议。
现在,如果您从 class 中调用方法,AOP 将无法正常工作。请参阅此答案以获得更清晰的信息- Spring AOP not working for method call inside another method
该项目使用 SpringBoot(2.3.4)
和 SpringCloud(Hoxton.SR8)
。
一共有三个类:BillController、BillService(接口)和BillServiceImpl(实现BillService),BillController调用BillService中声明的函数getBillList
。
BillServiceImpl中有两种方法,一种是getBillList
,另一种是simulateUnstableService
,getBillList
调用simulateUnstableService
,而在simulateUnstableService
中只是长眠(2000).
奇怪的是,如果我用 HystrixCommand
注释 getBillList
,那么它会像我预期的那样工作。但是如果我移动 HystrixCommand
来注释 simulateUnstableService
,那么就没有中断,这意味着超时不会触发 Circuit Breaker
。
@Service
public class BillServiceImpl implements BillService {
@Override
// have effact
@HystrixCommand(
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
}
)
public List<Bill> getBillList(long userId) {
return simulateUnstableService(userId);
}
// no effact
// @HystrixCommand(
// commandProperties = {
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
// }
// )
public List<Bill> simulateUnstableService(long userId) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new ArrayList<>();
}
}
此外,如果我只是将 simulateUnstableService
方法内容复制到 getBillList
,并使用 HystrixCommand 注释 getBillList,断路器也可以工作。
为什么?
当电路中断时调用回退方法。我们需要在 hystrix 命令中提及 fallback 方法。回退方法与 hystrix 注释的方法具有相同的签名。
simulateUnstableService 是你的后备方法吗?
@HystrixCommand(fallbackMethod='yourFallbackMethod'
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
}
)
public List<Bill> getBillList(long userId) {
return simulateUnstableService(userId);
}
此外,最好在 application.properties 文件中添加 hystrix 命令属性,而不是随注释一起提供。
问得好。
Hystrix 使用 AOP 包装被调用的方法并提供 Circuit Braking 功能。实际上有一个方面 class HystrixCommandAspect.java
定义了用于实现此目的的环绕建议。
现在,如果您从 class 中调用方法,AOP 将无法正常工作。请参阅此答案以获得更清晰的信息- Spring AOP not working for method call inside another method