我是靠谱客的博主 大意蜡烛,最近开发中收集的这篇文章主要介绍openFeign 异步 调用丢失上下文怎么破?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

大家好,我是不才陈某~

这是《Spring Cloud 进阶》第27篇文章,往期文章如下:

  • 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强?

  • openFeign夺命连环9问,这谁受得了?

  • 阿里面试这样问:Nacos、Apollo、Config配置中心如何选型?这10个维度告诉你!

  • 阿里面试败北:5种微服务注册中心如何选型?这几个维度告诉你!

  • 阿里限流神器Sentinel夺命连环 17 问?

  • 对比7种分布式事务方案,还是偏爱阿里开源的Seata,真香!(原理+实战)

  • Spring Cloud Gateway夺命连环10问?

  • Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!

  • 分布式链路追踪之Spring Cloud Sleuth夺命连环9问?

  • 链路追踪自从用了SkyWalking,睡的真香!

  • 3本书了,7万+字,10篇文章,《Spring Cloud 进阶》基础版 PDF

  • 妹子始终没搞懂OAuth2.0,今天整合Spring Cloud Security 一次说明白!

  • OAuth2.0实战!使用JWT令牌认证!

  • OAuth2.0实战!玩转认证、资源服务异常自定义这些骚操作!

  • 实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!

  • 字节面试这样问:跨库多表存在大量数据依赖问题有哪些解决方案?

  • 实战!退出登录时如何借助外力使JWT令牌失效?

  • 实战!Spring Cloud Gateway集成 RBAC 权限模型实现动态权限控制!

  • 实战!阿里神器 Seata 实现 TCC模式 解决分布式事务,真香!

  • 实战!openFeign如何实现全链路JWT令牌信息不丢失?

  • 微服务下蓝绿发布、滚动发布、灰度发布等方案,必须懂!

  • 微服务如何聚合 API 文档?这波秀~

  • Spring Cloud 2021.0.1 正式发布,卷不动了~

  • 实战!微服务 认证中心 如何扩展授权模式 实现多种方式登录?

  • Spring Cloud 再爆高危漏洞.... 赶紧修复!!

  • Spring Cloud Gateway 网关如何实现灰度发布?

最近有读者问了这样一个问题:陈哥,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的调用导致上下文丢失;前面有一篇文章说过这种问题:实战!openFeign如何实现全链路JWT令牌信息不丢失?

在集成OAuth2的时候如果做任何设置会丢失令牌信息,当时我们的解决方案是新建一个拦截器,如下:

@Component
@Slf4j
public class 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();

.....

最后说一句(别白嫖,求关注)

陈某每一篇文章都是精心输出,已经写了3个专栏,整理成PDF,获取方式如下:

  1. 《Spring Cloud 进阶》PDF:关注公众号:【码猿技术专栏】回复关键词 Spring Cloud 进阶 获取!

  2. 《Spring Boot 进阶》PDF:关注公众号:【码猿技术专栏】回复关键词 Spring Boot进阶 获取!

  3. 《Mybatis 进阶》PDF:关注公众号:【码猿技术专栏】回复关键词 Mybatis 进阶 获取!

如果这篇文章对你有所帮助,或者有所启发的话,帮忙点赞、在看、转发、收藏,你的支持就是我坚持下去的最大动力!

关注公众号:【码猿技术专栏】,公众号内有超赞的粉丝福利,回复:加群,可以加入技术讨论群,和大家一起讨论技术,吹牛逼!

求点赞、在看、分享三连b0e898af324b6a77404ebbdb6f9a1a4c.png

最后

以上就是大意蜡烛为你收集整理的openFeign 异步 调用丢失上下文怎么破?的全部内容,希望文章能够帮你解决openFeign 异步 调用丢失上下文怎么破?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部