解决feign调用session传不出去的问题

Feign调用服务Session失效问题以及使用RequestContextHolder.getRequestAttributes()获取值为null的问题 文章目录一、Feign调用服务Session失效问题二、RequestContextHolder.getRequestAttributes()获取值为null解决方式一 关闭Fegin的熔断解决方式二 调整隔离策略解决方式三 自定义并发策略 一、Feign调用服务Session失效问题 微服务使用feign相互之间调用时,存在session丢失的问题。例如,使用Feign调用某个远程API,这个远程API需要传递一个鉴权信息,我们可以把cookie里面的session信息放到Header里面,我们需要编写 阅读详情

微服务使用feign相互之间调用时,存在session丢失的问题。例如,使用Feign调用某个远程API,这个远程API需要传递一个鉴权信息,我们可以把cookie里面的session信息放到Header里面,这个Header是动态的,跟你的HttpRequest相关,我们选择编写一个拦截器来实现Header的传递,也就是需要实现RequestInterceptor接口,具体代码如下:

@Configuration  
@EnableFeignClients(basePackages = "com.xxx.xxx.client")  
public class FeignClientsConfigurationCustom implements RequestInterceptor {  

  @Override  
  public void apply(RequestTemplate template) {  

    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();  
    if (requestAttributes == null) {  
      return;  
    }  

    HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();  
    Enumeration<String> headerNames = request.getHeaderNames();  
    if (headerNames != null) {  
      while (headerNames.hasMoreElements()) {  
        String name = headerNames.nextElement();  
        Enumeration<String> values = request.getHeaders(name);  
        while (values.hasMoreElements()) {  
          String value = values.nextElement();  
          template.header(name, value);  
        }  
      }  
    }  

  }  

}  

经过测试,上面的解决方案可以正常的使用;
但是,当引入Hystrix熔断策略时,出现了一个新的问题;

RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

获取不到request信息,从而无法传递session信息,最终发现RequestContextHolder.getRequestAttributes()该方法是从ThreadLocal变量里面取得对应信息的,这就找到问题原因了,由于Hystrix熔断机制导致的。
Hystrix有隔离策略:THREAD以及SEMAPHORE,当隔离策略为 THREAD 时,是没办法拿到 ThreadLocal 中的值的。

因此有两种解决方案:

方案一:调整格隔离策略

hystrix.command.default.execution.isolation.strategy: SEMAPHORE

这样配置后,Feign可以正常工作。

但该方案不是特别好。原因是Hystrix官方强烈建议使用THREAD作为隔离策略! 可以参考官方文档说明

方案二:自定义策略

查看源码找到了
org.springframework.cloud.sleuth.instrument.hystrix.SleuthHystrixConcurrencyStrategy
这个类,查看SleuthHystrixConcurrencyStrategy的源码,继承了HystrixConcurrencyStrategy,用来实现了自己的并发策略。

/**

  • Abstract class for defining different behavior or implementations for concurrency related aspects of the system with default implementations.
  • For example, every {@link Callable} executed by {@link HystrixCommand} will call {@link #wrapCallable(Callable)} to give a chance for custom implementations to decorate the {@link Callable} with
  • additional behavior.
  • When you implement a concrete {@link HystrixConcurrencyStrategy}, you should make the strategy idempotent w.r.t ThreadLocals.
  • Since the usage of threads by Hystrix is internal, Hystrix does not attempt to apply the strategy in an idempotent way.
  • Instead, you should write your strategy to work idempotently. See https://github.com/Netflix/Hystrix/issues/351 for a more detailed discussion.
  • See {@link HystrixPlugins} or the Hystrix GitHub Wiki for information on configuring plugins: <a
  • href=“https://github.com/Netflix/Hystrix/wiki/Plugins”>https://github.com/Netflix/Hystrix/wiki/Plugins.
    */
    public abstract class HystrixConcurrencyStrategy

搜索发现有好几个地方继承HystrixConcurrencyStrategy类

其中就有我们熟悉的Spring Security和刚才提到的Sleuth都是使用了自定义的策略,同时由于Hystrix只允许有一个并发策略,因此为了不影响Spring Security和Sleuth,我们可以参考他们的策略实现自己的侧路,大致思路:
将现有的并发策略作为新并发策略的成员变量;
在新并发策略中,返回现有并发策略的线程池、Queue;
代码如下:

public class FeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {  

  private static final Logger log = LoggerFactory.getLogger(FeignHystrixConcurrencyStrategy.class);  
  private HystrixConcurrencyStrategy delegate;  

  public FeignHystrixConcurrencyStrategy() {  
    try {  
      this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();  
      if (this.delegate instanceof FeignHystrixConcurrencyStrategy) {  
        // Welcome to singleton hell...  
        return;  
      }  
      HystrixCommandExecutionHook commandExecutionHook =  
          HystrixPlugins.getInstance().getCommandExecutionHook();  
      HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier();  
      HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher();  
      HystrixPropertiesStrategy propertiesStrategy =  
          HystrixPlugins.getInstance().getPropertiesStrategy();  
      this.logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher, propertiesStrategy);  
      HystrixPlugins.reset();  
      HystrixPlugins.getInstance().registerConcurrencyStrategy(this);  
      HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);  
      HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);  
      HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);  
      HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);  
    } catch (Exception e) {  
      log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);  
    }  
  }  

  private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier,  
      HystrixMetricsPublisher metricsPublisher, HystrixPropertiesStrategy propertiesStrategy) {  
    if (log.isDebugEnabled()) {  
      log.debug("Current Hystrix plugins configuration is [" + "concurrencyStrategy ["  
          + this.delegate + "]," + "eventNotifier [" + eventNotifier + "]," + "metricPublisher ["  
          + metricsPublisher + "]," + "propertiesStrategy [" + propertiesStrategy + "]," + "]");  
      log.debug("Registering Sleuth Hystrix Concurrency Strategy.");  
    }  
  }  

  @Override  
  public <T> Callable<T> wrapCallable(Callable<T> callable) {  
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();  
    return new WrappedCallable<>(callable, requestAttributes);  
  }  

  @Override  
  public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,  
      HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize,  
      HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {  
    return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime,  
        unit, workQueue);  
  }  

  @Override  
  public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,  
      HystrixThreadPoolProperties threadPoolProperties) {  
    return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties);  
  }  

  @Override  
  public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {  
    return this.delegate.getBlockingQueue(maxQueueSize);  
  }  

  @Override  
  public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv) {  
    return this.delegate.getRequestVariable(rv);  
  }  

  static class WrappedCallable<T> implements Callable<T> {  
    private final Callable<T> target;  
    private final RequestAttributes requestAttributes;  

    public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) {  
      this.target = target;  
      this.requestAttributes = requestAttributes;  
    }  

    @Override  
    public T call() throws Exception {  
      try {  
        RequestContextHolder.setRequestAttributes(requestAttributes);  
        return target.call();  
      } finally {  
        RequestContextHolder.resetRequestAttributes();  
      }  
    }  
  }  
}  

至此,结合FeignClientsConfigurationCustom配置feign调用session丢失的问题完美解决

feign调用session丢失解决方案.txt feign调用session丢失解决方案, Hystrix传播ThreadLocal对象; 自定义熔断策略 立即下载

相关推荐

详解feign调用session丢失解决方案

主要介绍了详解feign调用session丢失解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

feign session 调用_springboot使用feign调用session传递失效解决方案

标题框架version1springboot1.5.9.release2springCloud1.2.4.release3eureka1.6.24feign9.5.0前言使用场景:由于我们项目使用的是微服务框架,各个服务之间的调用,使用的是feign调用,我们项目调用各个模块直接调用,如果涉及到跨服务调用的话,开始发现从request里面的什么东西都获取不到,登录的request的session肯...

weixin_39998998的博客 590

告别Keil4!手把手教你用Keil C51 V9.61编译51单片机代码(附最新激活方法)

本文详细介绍了Keil C51 V9.61在51单片机开发中的全栈升级指南,包括编译速度提升、调试器性能优化和现代开发支持等核心优势。通过智能安装方案、项目迁移实战和新特性深度应用,帮助开发者告别Keil4,大幅提升开发效率。附有最新激活方法和实用技巧,适用于嵌入式开发工程师。

weixin_26886855的博客 420

feign远程调用丢失请求头问题解决

背景 微服务调用的时候请求不会传递参数.比如调用方服务请求头中有cookie存放sessionId,而被调用方服务没有请求头,从而没有cookie信息,也就不能根据cookie中存放的sessionId获取session信息,影响后续操作. 解决办法 通过实现RequestInterceptor接口,完成对所有的Feign请求,传递请求头和请求参数。本质是通过ThreadLocal线程共享变量实现. 代码实现 package com.kenai.gulimall.order.feign; i..

qq_26496077的博客 1316

Box2D-Lite源码阅读笔记(2)

0.初始化函数 static void InitDemo(int index) { world.Clear(); numBodies = 0; numJoints = 0; bomb = NULL; demoIndex = index; demos[index](bodies, joints); } 在这个初始化函数中,一般会默认执行index=0的函数,这个函数就是一个示例,因为示例比较简单,所以也便于研究,示例效果如下。 就是一个方块。 进入第一个示例函数。(忽略我加的注释)

ARTELE的博客 976

巨某量引擎后台登录实战笔记 | Playwright自动化框架

自动化框架、Playwright、滑块、巨某量引擎、抖某音系

什么都会一点。 2080

fegin调用关于session,请求头传递参数问题

feign调用关于session,请求头,参数,传递问题。

xiao_xiao3601的博客 926

Fluent验证案例03:管道中湍流流动压降计算——采用kw-sst模型计算压降更为准确。

阅读(4053) 评论(0)本案例利用Fluent计算管道中湍流流动压降。

qq_15963745的博客 877

Feign Hystrix微服务调用Session传播

  在使用SpringCloud来构建微服务时,服务和服务之间的调用非常频繁,服务之间调用通常用feign和Hystrix结合来使用,当使用上游微服务调用下游微服务时,怎么将上游服务的请求信息传递到下游服务中去呢?Feign提供了Interceptor来设置请求下游服务的header等信息,如下: @Component public class FeignRequestInterceptor ...

weihao_的博客 4072

跨越边界:用MessagePipe实现无缝的进程间通信

MessagePipe是一个用于.NET平台的消息传递库,它专注于简化异步消息处理和进程间通信。通过提供一系列易于使用的API,开发者可以快速搭建起稳定可靠的通信管道,支持多种传输协议(如TCP、Unix域套接字等),并内置了序列化/反序列化功能,使得跨语言和跨平台的数据交换变得轻而易举。为了方便序列化和反序列化操作,我们需要为每种消息定义对应的类或结构体,并标记属性。这样可以确保消息在发送方和接收方之间正确无误地传递。[Key0set;[Key1set;

墨夶的博客 816

【Flink】FlinkCDC获取mysql数据时间类型差8小时时区解决方案

​ 1、背景: 在我们使用FlinkCDC采集mysql数据的时候,日期类型是我们很常见的类型,但是FlinkCDC读取出来会和数据库的日期时间不一致,情况如下 FlinkCDC获取的数据中create_time字段1694597238000转换为时间戳2023-09-13 17:27:18,而数据库中原始数据如下,并没有到下午5点,这就导致了FlinkCDC读出来的时间和数据库中实际的时间不一致的情况,与数据库对比可以发现,这里的时间戳与数据库时间刚好相差了 8 个小时,在实际生产中这种情况是不

一杯咖啡半杯糖的博客 3854

feign服务间调用保留session

feign调用保留session

weixin_51751186的博客 1247

GibbsCAM软件二次开发:GibbsCAM软件API接口详解

API(Application Programming Interface,应用程序编程接口)是一种允许不同软件之间进行通信的接口。在GibbsCAM软件中,API提供了与外部程序交互的能力,使得开发者可以利用GibbsCAM的强大功能进行二次开发,定制化满足特定的制造需求。GibbsCAM的API主要基于.NET框架,使用C#或VB.NET等语言进行编程。在GibbsCAM软件中,通过API接口创建自定义几何形状是实现复杂零件设计和加工策略定制的关键步骤。

kkchenjj的博客 1497

feign session 调用_Feign调用session丢失解决方案

最近做一个项目,用到springCloud,结果遇到session丢失的问题,从zuul->feign->shiro->boot都有问题,默认情况下,zuul和feign在转发时都会丢掉header,于是花时间研究下。转:https://blog.youkuaiyun.com/Crystalqy/article/details/79083857自定义RequestInterceptor使用F...

weixin_39590739的博客 404

【25届数字IC秋招总结】面试经验13——豪威科技面试

25届数字ic面试记录———豪威科技

lalala0635的博客 363

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

feign session 调用_详解feign调用session丢失解决方案

最近在做项目的时候发现,微服务使用feign相互之间调用时,存在session丢失的问题。例如,使用Feign调用某个远程API,这个远程API需要传递一个鉴权信息,我们可以把cookie里面的session信息放到Header里面,这个Header是动态的,跟你的HttpRequest相关,我们选择编写一个拦截器来实现Header的传递,也就是需要实现RequestInterceptor接口,具...

weixin_39716510的博客 242

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

feign调用session丢失解决方案

feign调用时session丢失解决方案;Hystrix传播ThreadLocal对象

Crystalqy的博客 2万+

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

SpringCloud中Feign调用微服务实现会话共享,session丢失问题

微服务使用feign相互之间调用时,存在session丢失的问题。 搞了好久这个问题,终于解决了。看到一篇大神的文章,特意记录一下,以后便于查找。 例如,使用Feign调用某个远程API,这个远程API需要传递一个鉴权信息,我们可以把cookie里面的session信息放到Header里面,这个Header是动态的,跟你的HttpRequest相关,我们选择编写一个拦截器来实现Header的传...

RyanJJ_的博客 3290

feign服务间调用session变更(失效)问题

在springcloud项目中,发现在服务之间的fegin调用时,session无法有效传递。我项目中用到了websocket,需要session保持一致性才能建立长连接。因此,需要保证fegin调用session的一致性——即服务1(user服务)调用服务2(teacher服务),服务1和服务2的sessionid一致。下面谈谈如何解决这个问题。 这是我在参考了大佬的写法之后自己整理的笔记 ...

隔壁老赵的博客 1525

feign session 调用_Spring-Cloud整合Spring-Session的注意点

今天刚学习,但原文中还没有更新关于如何整合Spring-Session。我就想动手试一试,结果遇到了不少问题,在这里记录下来,做一个分享。项目的结构很简单,就是zuul+feign+一个微服务的结构,然后想通过spring-session共享同一个session。通过简单的配置后,成功的运行了项目,但是发现zuul,feign,微服务中三处打印出来的sessionId都不相同。通过浏览器调试可以确...

weixin_35036750的博客 401

feign调用不经过网关

feign调用不经过网关,是一种http的调用 需要携带网关的session信息,创建一个feign的拦截器实现 RequestInterceptor 列子: @EnableFeignClients @Configuration public class FeignRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTempla.

weixin_45371902的博客 4730
上一篇: JVM系列(1)-----初始JVM
下一篇: 设计模式(一)--------七大软件设计原则
jackwang91
博客等级 码龄10年 3粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值