1.使用Feign 调用其他微服务,尤其是在多级调用的同时,需要将一些共同的参数传递至下一个服务,如:token。比较方便的做法是放在请求头中,在Feign调用的同时自动将参数放到restTemplate中。

2.具体做法是首先实现 RequestInterceptor

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
@Component
public class SecuringRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
requestTemplate.header(name, values);
}
}
}
}

3.RequestContextHolder.getRequestAttributes()该方法是从ThreadLocal变量里面取得相应信息的,当hystrix断路器的隔离策略为THREAD时,是无法取得ThreadLocal中的值。

解决方案:

(1). hystrix隔离策略换为SEMAPHORE。

(2)自定义策略,模仿Sleuth的trace传递。

具体可参考:http://www.itmuch.com/spring-cloud-sum/hystrix-threadlocal/

import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
import com.netflix.hystrix.strategy.properties.HystrixProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; @Component
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();
}
}
}
}

4.最后需要注意的是,如果是使用多线程的情况下,则需要在主线程调用其他线程前将RequestAttributes对象设置为子线程共享

ServletRequestAttributes attribute = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
RequestContextHolder.setRequestAttributes(attribute, true);

Spring Cloud 使用Feign调用服务传递Header中的参数的更多相关文章

  1. 【spring cloud】spring cloud 使用feign调用,1.fallback熔断器不起作用,2.启动报错Caused by: java.lang.ClassNotFoundException: com.netflix.hystrix.contrib.javanica.aop.aspectj.Hystri解决

    示例GitHub源码地址:https://github.com/AngelSXD/springcloud 1.首先使用feign调用,需要配置熔断器 2.配置熔断器需要将熔断器注入Bean,熔断器类上 ...

  2. spring cloud学习(二) 调用服务

    spring-cloud调用服务有两种方式,一种是Ribbon+RestTemplate, 另外一种是Feign. Ribbon是一个基于HTTP和TCP客户端的负载均衡器,其实feign也使用了ri ...

  3. Spring Cloud netflix feign【服务间通信】

    一.简介 1,进程间通讯的本质是交换消息 2,服务间通信的两种方式 (1)RESTFul风格 (2)RPC风格 (3)两种风格的比较 3.基于RESTFul风格服务调用模型 4.基于Spring Cl ...

  4. spring cloud(四) feign

    spring cloud 使用feign进行服务间调用 1. 新建boot工程 pom引入依赖 <dependency> <groupId>org.springframewor ...

  5. Spring Boot 和 Spring Cloud Feign调用服务及传递参数踩坑记录

    背景 :在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnectio ...

  6. spring cloud关于feign client的调用对象列表参数、设置header参数、多环境动态参数试配

    spring cloud关于feign client的调用 1.有些场景接口参数需要传对象列表参数 2.有些场景接口设置设置权限等约定header参数 3.有些场景虽然用的是feign调用,但并不会走 ...

  7. Spring Cloud第九篇 | 分布式服务跟踪Sleuth

    ​ ​本文是Spring Cloud专栏的第九篇文章,了解前八篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cl ...

  8. 《Spring Cloud与Docker微服务架构实战》配套代码

    不才写了本使用Spring Cloud玩转微服务架构的书,书名是<Spring Cloud与Docker微服务架构实战> - 周立,已于2017-01-12交稿.不少朋友想先看看源码,现将 ...

  9. Spring Cloud与Docker微服务架构实战 PDF

    电子版百度云下载 链接: https://pan.baidu.com/s/115u011CJ8MZzJx_NqutyTQ 提取码: 关注公众号[GitHubCN]回复2019获取 本书的代码 共计70 ...

随机推荐

  1. 学到了林海峰,武沛齐讲的Day51 django+数据库

    连不上,通过这一步解决 搞死了..辛苦但觉得值得 刷数据库 出问题 IDEA关联MySQL报错:Server returns invalid timezone. Go to ‘Advanced’ ta ...

  2. 18-Node.js学习笔记-Express-请求处理-构建模块化路由

    构建模块化路由 const express = require('express') //创建路由对象 const home = express.Router(); //将路由和请求路径进行匹配 ap ...

  3. Python天天学_02_基础二

    Python_day_02 金角大王:http://www.cnblogs.com/alex3714/articles/5717620.html ------Python是一个优雅的大姐姐 学习方式: ...

  4. php上传大文件1G

    前段时间做视频上传业务,通过网页上传视频到服务器. 视频大小 小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制:2,请求时间过长, ...

  5. CSP-S2 游记

    CSP-S2 游记 & AFO 感想 Day0 早上考了一场式,非常简单,但是懒得写正解.230pts. 晚上听了一下WYQ大神的考前直播,写了一下树上倍增(我是不会告诉你我还写炸了) 与lu ...

  6. Python字典里的5个黑魔法

    Python里面有3大数据结构:列表,字典和集合.字典是常用的数据结构,里面有一些重要的技巧用法,我把这些都整理到一起,熟练掌握这些技巧之后,对自己的功力大有帮助. 1.字典的排序: 用万金油sort ...

  7. 并发编程--Concurrent-工具类介绍

    并发编程--Concurrent-工具类介绍 并发编程--Concurrent-工具类介绍 CountDownLatch CylicBarrier Semaphore Condition 对象监视器下 ...

  8. 【Spark机器学习速成宝典】基础篇01Windows下spark开发环境搭建+sbt+idea(Scala版)

    注意: spark用2.1.1 scala用2.11.11 材料准备 spark安装包 JDK 8 IDEA开发工具 scala 2.11.8 (注:spark2.1.0环境于scala2.11环境开 ...

  9. 从curl命令获取libcurl的用法

    libcurl的用法参数太多 有时候弄不好 可以先用curl命令实现了 然后获取相应的libcurl代码 比如要上传文件 curl -T d:/h.txt http://demo.xudp.cn/up ...

  10. 批处理bat相关

    时间 %date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2% 判断 if %date:~2,1%==/ (echo en ...