场景:
用户登陆后,再次访问网页,将用户信息loginToken放在request的header中,首先经过网关,然后到达A服务,然后A服务调用B服务时如何把loginToken传递给B服务
1.修改hytrix配置,配置hytrix的 strategy为 SEMAPHORE。
Hystrix 提供两种执行隔离策略( ExecutionIsolationStrategy ) :SEMAPHORE
、THREAD
-
SEMAPHORE
:信号量,命令在调用线程执行。 -
THREAD
:线程池,命令在线程池执行。
如果不修改配置,默认配置的为THREAD,因为不在同一个线程中,无法获得请求的上下文对象,无法执行第二步操作
feign: httpclient: enabled: false okhttp: enabled: true hystrix: enabled: true hystrix: command: default: execution: timeout: enabled: true isolation: strategy: SEMAPHORE thread: timeoutInMilliseconds: 60000
2.增加拦截器
feign提供的 RequestInterceptor 接口会默认拦截feign发出去所有请求,所以在这里拦截服务A发送给服务B的请求,然后再请求头中添加loginToken
如果再第一步没有修改 hystrix 的 strategy,则这一步中 RequestContextHolder.getRequestAttributes()的结果无法获取到,结果为null
package com.yuanian.example.feignA.config; import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; /** * @author liujy * @date 2019/10/24 10:57 **/ @Component public class FeignTokenInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { HttpServletRequest request = getServletRequest(); if (null == request){ return; } template.header("loginToken", getHeaders(request)); } private HttpServletRequest getServletRequest() { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); return ((ServletRequestAttributes) requestAttributes).getRequest(); } private String getHeaders(HttpServletRequest request){ return request.getHeader("loginToken"); } }