在官方https://spring.io/guides/gs/circuit-breaker/手册中有
@HystrixCommand(fallbackMethod = "reliable") public String readingList() { URI uri = URI.create("http://localhost:8090/recommended"); return this.restTemplate.getForObject(uri, String.class); } public String reliable() { return "Cloud Native Java (O'Reilly)"; }
如何将数据从业务方法传递给回退方法?使用ThreadLocal,不可变集合,并发集合,任何想法/最佳实践?
使用ThreadLocal?
@HystrixCommand
和相应的fallbackMethod
通常在一个单独的线程中执行(一起),因为默认的execution.isolation.strategy
是ExecutionIsolationStrategy.THREAD
。
因此,这意味着如果在执行@HystrixCommand
之前使用ThreadLocal设置任何变量,则@HystrixCommand
将无法使用它们,因为线程将不同。
如果以上是必要的,您可以使用不同的隔离策略 - ExecutionIsolationStrategy.SEMAPHORE
。
要覆盖默认隔离策略,可以在hystrix命令定义(或属性文件)中执行此操作:
@HystrixCommand(fallbackMethod = "reliable",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
}
)
使用@HystrixCommand
注释的方法和相应的fallbackMethod需要具有相同的方法签名(在抛出的异常的回退中加上可选的param),因此回退方法自然可以访问@HystrixCommand
的所有输入参数。
在fallback方法签名中添加Throwable将包含从@HystrixCommand
生成的异常:
public String reliable(Throwable t) {
return "Cloud Native Java (O'Reilly)";
}
期望将任何执行数据从main方法传递到fallback方法是不切实际的。您不知道主方法何时失败。关键是尝试定义更好的输入参数,无论如何都要与回退共享。
例如,在您给出的代码中,URL可以成为输入参数,因此它也可用于回退方法:
@HystrixCommand(fallbackMethod = "reliable")
public String readingList(String url) {
URI uri = URI.create(url);
return this.restTemplate.getForObject(uri, String.class);
}
public String reliable(String url, Throwable t) {
return "Cloud Native Java (O'Reilly)";
}