一料仗、Feign遠(yuǎn)程調(diào)用丟失請(qǐng)求頭問題
Feign在遠(yuǎn)程調(diào)用時(shí),會(huì)重新包裝請(qǐng)求(請(qǐng)求路徑立轧,請(qǐng)求參數(shù))但是不會(huì)攜帶請(qǐng)求頭,所以在到達(dá)被調(diào)服務(wù)時(shí)沒有請(qǐng)求頭信息
1帐萎、 SynchronousMethodHandler
@Override
public Object invoke(Object[] argv) throws Throwable {
RequestTemplate template = buildTemplateFromArgs.create(argv);
Options options = findOptions(argv);
Retryer retryer = this.retryer.clone();
while (true) {
try {
return executeAndDecode(template, options);
} catch (RetryableException e) {
try {
retryer.continueOrPropagate(e);
} catch (RetryableException th) {
Throwable cause = th.getCause();
if (propagationPolicy == UNWRAP && cause != null) {
throw cause;
} else {
throw th;
}
}
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
}
continue;
}
}
}
Feign遠(yuǎn)程調(diào)用丟失請(qǐng)求頭.png
2胜卤、解決方案
在Feign重新包裝請(qǐng)求時(shí),使用 RequestInterceptor 攔截器葛躏,把老請(qǐng)求中請(qǐng)求頭重新保存到新的請(qǐng)求中給Feign遠(yuǎn)程調(diào)用請(qǐng)求添加請(qǐng)求頭.png
二、多線程下Feign遠(yuǎn)程調(diào)用丟失上下文
多線程下Feign遠(yuǎn)程調(diào)用丟失上下文.png
多線程下Feign遠(yuǎn)程調(diào)用丟失上下文.png
- 解決方案
把線程-1中的上下文內(nèi)容拷貝到 線程-2 悔醋、 線程-3
public OrderConfirmVo orderConfirm() {
OrderConfirmVo orderConfirm = new OrderConfirmVo();
//獲取登錄用戶
MemberEntity memberInfo = LoginInterceptor.threadLocal.get();
log.info("主線程兽叮。。鹦聪。" + Thread.currentThread().getId());
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//1、獲取用戶地址
CompletableFuture<Void> addressFuture = CompletableFuture.runAsync(() -> {
log.info("addressFuture線程宰僧。。琴儿。" + Thread.currentThread().getId());
// 把主線程中的屬性共享給其他線程
RequestContextHolder.setRequestAttributes(requestAttributes);
R addressRes = this.memberClient.fetchAddressByMemberId(memberInfo.getId());
String addressJSON = JSON.toJSONString(addressRes.get("data"));
List<MemberReceiveAddressEntity> memberReceiveAddressEntityList = JSON.parseObject(addressJSON, new TypeReference<List<MemberReceiveAddressEntity>>() {
});
if (memberReceiveAddressEntityList != null && memberReceiveAddressEntityList.size() > 0) {
List<MemberAddressTo> addressList = memberReceiveAddressEntityList.stream().map(address -> {
MemberAddressTo memberAddressTo = new MemberAddressTo();
BeanUtils.copyProperties(address, memberAddressTo);
return memberAddressTo;
}).collect(Collectors.toList());
orderConfirm.setAddressList(addressList);
}
}, this.executor);
//2造成、購物項(xiàng)
CompletableFuture<Void> cartItemFuture = CompletableFuture.runAsync(() -> {
log.info("addressFuture線程。晒屎。缓升。" + Thread.currentThread().getId());
// 把主線程中的屬性共享給其他線程
RequestContextHolder.setRequestAttributes(requestAttributes);
R cartRes = this.cartClient.fetchSelectedCartItems();
String cartJson = JSON.toJSONString(cartRes.get("data"));
List<CartItem> cartItemToList = JSON.parseObject(cartJson, new TypeReference<List<CartItem>>() {
});
if (cartItemToList != null && cartItemToList.size() > 0) {
List<CartItemTo> cartItemList = cartItemToList.stream().filter(item -> item.getCheck() == true).map(item -> {
CartItemTo itemTo = new CartItemTo();
BeanUtils.copyProperties(item, itemTo);
return itemTo;
}).collect(Collectors.toList());
orderConfirm.setCartItemList(cartItemList);
}
}, this.executor);
//3、優(yōu)惠券
orderConfirm.setIntegration(memberInfo.getIntegration());
try {
CompletableFuture.allOf(addressFuture, cartItemFuture).get();
} catch (Exception e) {
e.printStackTrace();
throw new RavenException(RavenCodeEnum.THREAD_POOL_FAIL);
}
return orderConfirm;
}