@GetMapping(value = "/getServerInfo/{serviceName}")
public String getServer1Info(@PathVariable(value = "serviceName") String serviceName) {
LOGGER.info("当前线程ID:" + Thread.currentThread().getId() + "当前线程Name" + Thread.currentThread().getName());
RequestContextHolder.currentRequestAttributes().setAttribute("context", "main-thread-context", SCOPE_REQUEST);
return consumeService.getServerInfo(serviceName);
}
@Override
@HystrixCommand(fallbackMethod = "getServerInfoFallback",
commandProperties = {@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD")},
commandKey = "cust2GetServerInfo",
threadPoolKey = "cust2ThreadPool",
groupKey = "cust2")
public String getServerInfo(String serviceName) {
LOGGER.info(RibbonFilterContextHolder.getCurrentContext().get("TAG"));
LOGGER.info(RequestContextHolder.currentRequestAttributes().getAttribute("context", SCOPE_REQUEST).toString());
//如果是service1则需要添加http认证头,service1暂时添加了认证机制;反之service2不需要认证直接发出请求即可
if ("service1".equals(serviceName)) {
HttpEntity requestEntity = new HttpEntity(getHeaders());
ResponseEntity responseEntity = restTemplate.exchange("http://" + serviceName + "/getServerInfo?userName=shuaishuai", HttpMethod.GET, requestEntity, String.class);
return responseEntity.getBody();
} else
return restTemplate.getForObject("http://" + serviceName + "/getServerInfo?userName=shuaishuai", String.class);
}
public String getServerInfoFallback(String serviceName, Throwable e) {
if (e != null) {
LOGGER.error(e.getMessage());
}
return "Maybe the server named " + serviceName + " is not normal running";
}
而在RequestContextHolder中变量定义如下
类别
|
抽象实现
|
Event Notifier
|
HystrixEventNotifier
|
Metrics Publisher
|
HystrixMetricsPublisher
|
Properties Strategy
|
HystrixPropertiesStrategy
|
Concurrency Strategy
|
HystrixConcurrencyStrategy
|
Command Execution Hook
|
HystrixCommandExecutionHook
|
public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
@Override
public Callable wrapCallable(Callable callable) {
return new RequestAttributeAwareCallable<>(callable, RequestContextHolder.getRequestAttributes());
}
static class RequestAttributeAwareCallable implements Callable {
private final Callable delegate;
private final RequestAttributes requestAttributes;
public RequestAttributeAwareCallable(Callable callable, RequestAttributes requestAttributes) {
this.delegate = callable;
this.requestAttributes = requestAttributes;
}
@Override
public T call() throws Exception {
try {
RequestContextHolder.setRequestAttributes(requestAttributes);
return delegate.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
}
@PostConstruct
public void init() {
HystrixPlugins.getInstance().registerConcurrencyStrategy(new RequestContextHystrixConcurrencyStrategy());
}
public interface HystrixCallableWrapper {
/**
* 包装Callable实例
*
* @param callable 待包装实例
* @param 返回类型
* @return 包装后的实例
*/
Callable wrap(Callable callable);
}
public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
private final Collection wrappers;
public RequestContextHystrixConcurrencyStrategy(Collection wrappers) {
this.wrappers = wrappers;
}
@Override
public Callable wrapCallable(Callable callable) {
return new CallableWrapperChain(callable, wrappers.iterator()).wrapCallable();
}
private static class CallableWrapperChain {
private final Callable callable;
private final Iterator wrappers;
CallableWrapperChain(Callable callable, Iterator wrappers) {
this.callable = callable;
this.wrappers = wrappers;
}
Callable wrapCallable() {
Callable delegate = callable;
while (wrappers.hasNext()) {
delegate = wrappers.next().wrap(delegate);
}
return delegate;
}
}
}
public final class RequestAttributeAwareCallableWrapper implements HystrixCallableWrapper {
@Override
public Callable wrap(Callable callable) {
return new RequestAttributeAwareCallable(callable, RequestContextHolder.getRequestAttributes());
}
static class RequestAttributeAwareCallable implements Callable {
private final Callable delegate;
private final RequestAttributes requestAttributes;
RequestAttributeAwareCallable(Callable callable, RequestAttributes requestAttributes) {
this.delegate = callable;
this.requestAttributes = requestAttributes;
}
@Override
public T call() throws Exception {
try {
RequestContextHolder.setRequestAttributes(requestAttributes);
return delegate.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
}
public class MdcAwareCallableWrapper implements HystrixCallableWrapper {
@Override
public Callable wrap(Callable callable) {
return new MdcAwareCallable<>(callable, MDC.getCopyOfContextMap());
}
private class MdcAwareCallable implements Callable {
private final Callable delegate;
private final Map contextMap;
public MdcAwareCallable(Callable callable, Map contextMap) {
this.delegate = callable;
this.contextMap = contextMap != null ? contextMap : new HashMap();
}
@Override
public T call() throws Exception {
try {
MDC.setContextMap(contextMap);
return delegate.call();
} finally {
MDC.clear();
}
}
}
}
@Bean
public HystrixCallableWrapper requestAttributeAwareCallableWrapper() {
return new RequestAttributeAwareCallableWrapper();
}
@Bean
public HystrixCallableWrapper mdcAwareCallableWrapper(){
return new MdcAwareCallableWrapper();
}
@Autowired(required = false)
private List wrappers = new ArrayList<>();
@PostConstruct
public void init() {
HystrixPlugins.getInstance().registerConcurrencyStrategy(new RequestContextHystrixConcurrencyStrategy(wrappers));
}