[SpringCloud-Feign] Feign转发请求头,(防止session失效)
方案1
获取: @RequestMapping(value = "/api/test", method = RequestMethod.GET) public String testFun(@RequestParam String name, @RequestHeader("uniqueId") String uniqueId) { if(uniqueId == null ){ return "Must defined the uniqueId , it can not be null"; } log.info(uniqueId, "begin testFun... "); return uniqueId; }
然后A使用Feign调用B服务的时候,传过去:
@FeignClient(value = "DEMO-SERVICE") public interface CallClient { /** * 访问DEMO-SERVICE服务的/api/test接口,通过注解将logId传递给下游服务 */ @RequestMapping(value = "/api/test", method = RequestMethod.GET) String callApiTest(@RequestParam(value = "name") String name, @RequestHeader(value = "uniqueId") String uniqueId); }
方案弊端:毫无疑问,这方案不好,因为对代码有侵入,需要开发人员没次手动的获取和添加,因此舍弃
方案2
服务通过请求拦截器,在请求从A发送到B之后,在拦截器内将自己需要的东东加到请求头:
网上很多关于这种方法的博文或者资料,大同小异,但是有一个问题,在开启熔断器之后,这里的attrs就是null,因为熔断器默认的隔离策略是thread,也就是线程隔离,实际上接收到的对象和这个在发送给B不是一个线程,怎么办?有一个办法,修改隔离策略hystrix.command.default.execution.isolation.strategy=SEMAPHORE,改为信号量的隔离模式,但是不推荐,因为thread是默认的,而且要命的是信号量模式,熔断器不生效,比如设置了熔断时间hystrix.command.default.execution.isolation.semaphore.timeoutInMilliseconds=5000,五秒,如果B服务里面sleep了10秒,非得等到B执行完毕再返回,因此这个方案也不可取;但是有什么办法可以在默认的Thread模式下让拦截器拿到上游服务的请求头?自定义策略:代码如下:
然后使用默认的熔断器隔离策略,也可以在拦截器内获取到上游服务的请求头信息了; 这里参考的博客,感谢这位大牛:
下一篇:
第二篇:RabbitMQ的工作模式