@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<String> requestEntity = new HttpEntity<String>(getHeaders());
ResponseEntity<String> 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 | |
Metrics Publisher | |
Properties Strategy | |
Concurrency Strategy | |
Command Execution Hook |
public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
return new RequestAttributeAwareCallable<>(callable, RequestContextHolder.getRequestAttributes());
}
static class RequestAttributeAwareCallable<T> implements Callable<T> {
private final Callable<T> delegate;
private final RequestAttributes requestAttributes;
public RequestAttributeAwareCallable(Callable<T> 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 <T> 返回類型
* @return 包裝後的實例
*/
<T> Callable<T> wrap(Callable<T> callable);
}
public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
private final Collection<HystrixCallableWrapper> wrappers;
public RequestContextHystrixConcurrencyStrategy(Collection<HystrixCallableWrapper> wrappers) {
this.wrappers = wrappers;
}
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
return new CallableWrapperChain(callable, wrappers.iterator()).wrapCallable();
}
private static class CallableWrapperChain<T> {
private final Callable<T> callable;
private final Iterator<HystrixCallableWrapper> wrappers;
CallableWrapperChain(Callable<T> callable, Iterator<HystrixCallableWrapper> wrappers) {
this.callable = callable;
this.wrappers = wrappers;
}
Callable<T> wrapCallable() {
Callable<T> delegate = callable;
while (wrappers.hasNext()) {
delegate = wrappers.next().wrap(delegate);
}
return delegate;
}
}
}
public final class RequestAttributeAwareCallableWrapper implements HystrixCallableWrapper {
@Override
public <T> Callable<T> wrap(Callable<T> callable) {
return new RequestAttributeAwareCallable(callable, RequestContextHolder.getRequestAttributes());
}
static class RequestAttributeAwareCallable<T> implements Callable<T> {
private final Callable<T> delegate;
private final RequestAttributes requestAttributes;
RequestAttributeAwareCallable(Callable<T> 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 <T> Callable<T> wrap(Callable<T> callable) {
return new MdcAwareCallable<>(callable, MDC.getCopyOfContextMap());
}
private class MdcAwareCallable<T> implements Callable<T> {
private final Callable<T> delegate;
private final Map<String, String> contextMap;
public MdcAwareCallable(Callable<T> callable, Map<String, String> 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<HystrixCallableWrapper> wrappers = new ArrayList<>();
@PostConstruct
public void init() {
HystrixPlugins.getInstance().registerConcurrencyStrategy(new RequestContextHystrixConcurrencyStrategy(wrappers));
}