如上图,当业务中需要config模块接口需要用到system模块的接口,需要用到feign来进行远程调用。
1、首先在生产者里面定义一个对外暴露的feign
2、在消费者里面注入SiteFeign,调用接口
3、编写FeignClientsConfiguration类,实现Requstinterceptor(此类为了传递token)
@Configuration
public class FeignClientsConfiguration implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
// 此种方式是线程安全的
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
// 不为空时取出请求中的header 原封不动的设置到feign请求中
if (null != attributes) {
HttpServletRequest request = attributes.getRequest();
// 遍历设置 也可从request取出整个Header 写到RequestTemplate 中
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
// 跳过 content-length
if (name.equals("content-length")){
continue;
}
requestTemplate.header(name, values);
}
}
}
}
}
注意:如果没有下面代码会报 :::Feign报错feign.RetryableException: too many bytes written executing 的错误!!
4、在生产者的@FeignClient的configuration属性来进行配置!
5、做完以上操作,需要在配置文件中进行feign的配置!!!(在消费者方的配置文件进行配置,假如a调用b,那就是在a的yml文件中配置)
feign:
hystrix:
command:
default:
execution:
timeout:
#如果enabled设置为false,则请求超时交给ribbon控制
enabled: true
isolation:
strategy: SEMAPHORE # 隔离策略
thread:
# 熔断器超时时间,默认:1000/毫秒
timeoutInMilliseconds: 20000
client:
config:
default: #配置全局的feign的配置 如果有指定的服务配置 默认的配置不会生效
connectTimeout: 60000 # 指定的是消费者连接服务提供者的连接超时时间,单位是毫秒
readTimeout: 20000 # 指定的是调用服务提供者的服务的超时时间,单位是毫秒
requestInterceptors: # 指定的是feign 自定义拦截器的相对路径
- com.terton.aisp.common.configuration.FeignClientsConfiguration
# loggerLevel: full # 配置日志等级
注意:::
如果引入熔断器,熔断策略必须配置为SEMAPHORE;未引入熔断器可以使用官方推荐的THREAD
原因:
当隔离策略为 THREAD 时,是没办法拿到 ThreadLocal 中的值的, 因为在RequestContextHolder 原码中使用了两个ThreadLocal ,而你的熔断策略是线程隔离的,返回值就成了null
重启服务就可以实现多服务间的token传递和调用