网站首页 > 教程文章 正文
最近有读者问了这样一个问题:openFeign异步调用总是失败触发Sentinel的降级,同步调用就没问题?
他还给我晒了一下代码,大致如下:
CompletableFuture<T> future1 = CompletableFuture.supplyAsync(() -> {
//openfeign的调用
return feign.remoteCall();
},executor);
CompletableFuture<T> future2 = CompletableFuture.supplyAsync(() -> {
//openfeign的调用
return feign.remoteCall();
},executor);
CompletableFuture.allOf(future1,future2).join();
.....
这种情况你遇到过吗?
如何解决?
这个算是常见问题了:feign的调用导致上下文丢失;
在集成OAuth2的时候如果做任何设置会丢失令牌信息,当时我们的解决方案是新建一个拦截器,如下:
@Component
@Slf4j
publicclass FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
HttpServletRequest httpServletRequest = RequestContextUtils.getRequest();
Map<String, String> headers = getHeaders(httpServletRequest);
for (Map.Entry<String, String> entry : headers.entrySet()) {
template.header(entry.getKey(), entry.getValue());
}
}
/**
* 获取原请求头
*/
private Map<String, String> getHeaders(HttpServletRequest request) {
Map<String, String> map = new LinkedHashMap<>();
Enumeration<String> enumeration = request.getHeaderNames();
if (enumeration != null) {
while (enumeration.hasMoreElements()) {
String key = enumeration.nextElement();
String value = request.getHeader(key);
if (StrUtil.equals(OAuthConstant.TOKEN_NAME,key)){
map.put(key, value);
break;
}
}
}
return map;
}
}
上述代码根本逻辑就是将请求头中Token信息放入RequestTemplate的头中。
注意:这里取出请求头中信息用的是RequestContextHolder。
看到这里是不是明白了,RequestContextHolder中是将请求信息放入ThreadLocal中的,只能取到同一个线程的数据。
因此要解决异步调用的问题,只需要在发起远程调用之前给异步线程添加上主线程的上下文信息,此时最上方调用失效的代码变成如下:
//获取主线程的请求信息
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
CompletableFuture<T> future1 = CompletableFuture.supplyAsync(() -> {
//将主线程的请求信息设置到异步线程中,否则会丢失请求上下文,导致调用失败
RequestContextHolder.setRequestAttributes(attributes);
//openfeign的调用
return feign.remoteCall();
},executor);
CompletableFuture<T> future2 = CompletableFuture.supplyAsync(() -> {
//将主线程的请求信息设置到异步线程中,否则会丢失请求上下文,导致调用失败
RequestContextHolder.setRequestAttributes(attributes);
//openfeign的调用
return feign.remoteCall();
},executor);
CompletableFuture.allOf(future1,future2).join();
.....
- 上一篇: Win10任务栏卡死、无响应、点不动的解决方法
- 下一篇: Feign作为HTTP客户端调用远程服务
猜你喜欢
- 2025-09-11 Spring Boot3 中 RESTful 接口调用全解析:从阻塞到响应式的实战指南
- 2025-09-11 springcloud实战:服务间通信OpenFeign熔断
- 2025-09-11 项目终于用上了动态Feign,真香!_feign动态服务名
- 2025-09-11 RestTemplate和Feign的区别_feign和httpclient的区别
- 2025-09-11 OpenFeign:让你的Java代码像本地调用一样简单
- 2025-09-11 【完结14章】SpringCloud+Netty集群实战千万级 IM系统
- 2025-09-11 Eureka服务发现框架和微服务调用组件Feign
- 2025-09-11 Spring Cloud OpenFeign - 远程调用
- 2025-09-11 「SpringCloud」(十二)OpenFeign+Ribbon实现负载均衡
- 2025-09-11 微服务 - 服务接口调用 OpenFeign
- 最近发表
-
- K8s 部署频繁出错?一套流程教你快速定位故障,工作效率翻倍
- 防火墙服务无法启用,显示灰色的解决办法
- 网络问题-电脑无法上网处理思路以及办法 (总集)
- Win10学院:Windows Denfender无法启动怎么办?
- Windows账户登录问题解决方案_登录windows账户什么意思
- IIS无法启动提示计算机上"."的服务W3SVC,一分钟搞定,抓紧收藏
- 已申请到免费顶级域名如何管理_顶级域名免费注册
- 网站被劫持了老是跳转怎么办_网站被劫持到其它网站如何解决
- 这些“常用药”被注销!涉及维生素、去痛片、眼药水等!快看看你家有吗?
- 《皕宋楼藏书志》清 藏书家陆心源与其门人李宗莲合编的藏书目录
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)