背景
项目使用Spring Cloud Eureka进行RPC调用,我们暂称调用服务为client,被调用服务为server;
有个场景是client调用某一个server的时候需要加token,但是调用其他服务不需要;
众所周知,RequestInterceptor就是用于微服务调用的时候加请求头的拦截器,但是实现当前拦截器也无法实现部分拦截的作用
实现
方案是,我们可以利用线程ThreadLocal+拦截器的方式存储标识,在拦截器中再判断是否需要加token,client端实现如下:
/**
* 增加标识的拦截器
*/
@Component
@Aspect
public class TokenFlagInterceptor{
public static final String TOKEN_FLAG = "token";
public static final String TOKEN_FLAG_VALUE = "y";
// 根据业务需求进行拦截
@Pointcut("execution(* com.mbcloud.trip.core.manger.TripAccManger.*(..))")
public void pointcut(){}
@Before("pointCut()")
public void before(){
Map<String,String> mdcMap = MDC.getCopyOfContextMap();
mdcMap.put(TOKEN_FLAG, TOKEN_FLAG_VALUE );
MDC.setContextMap(mdcMap);
}
@After("pointCut()")
public void after(){
MDC.remove(TOKEN_FLAG);
}
}
/**
* 请求拦截器
*/
@Configuration
public class FeginClientInterceptor implements RequestInterceptor{
@Override
public void apply(RequestTemplate requestTemplate){
if(MDC.get(TokenFlagInterceptor.TOKEN_FLAG )!=null){
//TODO 根据业务需求获取token
requestTemplate.header("token","124");
}
}
}
问题
如果服务中将hystrix打开了,配置fegin.hystrix.enabled=true
,那这个实现在调试的时候也许发现永远也无法加上token
因为hytrix默认的隔离策略是线程方式,上面的标识拦截器和请求拦截器不会在一个线程中执行,会导致标识失效,我们可以加上配置hystrix.command.default.execution.isolation.strategy=SEMAPHORE
,就可以解决了
如果只想小范围的修改隔离策略,可以使用 hystrix.command.AccTalkClient.getAccessToken(String).execution.isolation.strategy=SEMAPHORE
网友评论