详解 Feign 调用 Session 丢失解决方案
Feign 是一个基于 Java 的声明式 Web 服务客户端,提供了一个简单的方式来调用远程服务。但是在使用 Feign 调用远程服务时,可能会出现 Session 丢失的问题,本文将详解 Feign 调用 Session 丢失解决方案。
Feign 调用 Session 丢失问题的原因是由于 Feign 不会自动传递 Session 信息,导致在调用远程服务时无法获取到 Session 信息。解决这个问题需要实现 RequestInterceptor 接口,通过拦截器来传递 Header 信息,包括 Session 信息。
具体的解决方案代码如下:
```java
@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();此时 requestAttributes 会返回 null,从而无法传递 Session 信息。
这个问题的原因是由于 Hystrix 的熔断机制导致的。Hystrix 有两个隔离策略:THREAD 和 SEMAPHORE,当隔离策略为 THREAD 时,是没办法拿到 ThreadLocal 中的值的。
解决这个问题有两种方案:
方案一:调整隔离策略
可以通过调整 Hystrix 的隔离策略为 SEMAPHORE 来解决这个问题。例如,在 application.properties 文件中添加以下配置:
```properties
hystrix.command.default.execution.isolation.strategy: SEMAPHORE
```
这个方案可以解决问题,但是不是特别好,因为 Hystrix 官方强烈建议使用 THREAD 作为隔离策略。
方案二:自定义策略
可以通过自定义策略来解决这个问题。例如,使用 Sleuth 的熔断机制来传递 Trace 信息。Sleuth 提供了一个 org.springframework.cloud.sleuth.instrument.hystrix.SleuthHystrixConcurrencyStrategy 类,用于实现自己的并发策略。
Feign 调用 Session 丢失解决方案可以通过实现 RequestInterceptor 接口来解决,但是当引入 Hystrix 熔断策略时,需要调整隔离策略或自定义策略来解决问题。