相关配置可以用Bean或者配置文件两种方式实现,此处用Bean实现。
超时时间配置
connectTimeout: 防止由于较长的服务处理时间而阻塞调用者
readTimeout: 从建立连接开始计算,太长时间未返回响应时触发
/**
* feign超时时间配置
* @return
*/
@Bean
public Request.Options options() {
return new Request.Options(3000, 5000);
}
契约配置
Spring Cloud在feign上做了扩展,使之可以支持springMVC的注解。OpenFeign默认使用springMVContract。如果想使用Feign原生注解,可以修改配置。
/**
* 修改契约配置,支持Feign原生的注解
* @return
*/
@Bean
public Contract feignContract() {
return new Contract.Default();
}
http组件配置
feign原生http组件较老性能较低,官方推荐使用 Apache HttpClient5。只需要引入依赖即可使用。
<!-- Apache HttpClient5 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hc5</artifactId>
</dependency>
GZIP压缩配置
开启压缩可以节省网络资源
spring:
cloud:
openfeign:
compression: # 配置 GZIP 来压缩数据
request:
enabled: true
mime-types: text/xml,application/xml,application/json
min-request-size: 1024 # 最小请求压缩阈值
response:
enabled: true
编码器解码器配置
可以配置编码器解码器支持不同的数据格式。自定义编码器解码器只需要实现feign.codec.Decoder和feign.codec.Encoder。Feign提供了多种编解码器实现。
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
</dependency>
@Bean
public Decoder decoder() {
return new JacksonDecoder();
}
@Bean
public Encoder encoder() {
return new JacksonEncoder();
}
拦截器配置
通过拦截器可以实现token等信息在服务之间传递。seata的全局事务id就是通过拦截器实现的。
创建拦截器实现
@Slf4j
public class FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
// 业务逻辑 模拟认证逻辑
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
if(null != attributes){
HttpServletRequest request = attributes.getRequest();
String access_token = request.getHeader("Authorization");
log.info("从Request中解析请求头:{}",access_token);
//设置token
template.header("Authorization",access_token);
}
}
}
配置bean
@Bean
public FeignRequestInterceptor interceptor() {
return new FeignRequestInterceptor();
}
bean配置到文件中,在FeignClient指定配置文件。
import com.hoitung.fyz.interceptor.FeignRequestInterceptor;
import feign.Contract;
import feign.Request;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.context.annotation.Bean;
public class FeignConfiguration {
/**
* feign超时时间配置
* @return
*/
@Bean
public Request.Options options() {
return new Request.Options(3000, 5000);
}
/**
* 修改契约配置,支持Feign原生的注解
* @return
*/
@Bean
public Contract feignContract() {
return new Contract.Default();
}
@Bean
public Decoder decoder() {
return new JacksonDecoder();
}
@Bean
public Encoder encoder() {
return new JacksonEncoder();
}
@Bean
public FeignRequestInterceptor interceptor() {
return new FeignRequestInterceptor();
}
}
@FeignClient(name = "mall-storage", path = "/storage", configuration = FeignConfiguration.class)
public interface StorageServiceFeignClient {
@GetMapping("/get")
Integer getStorage(@RequestParam("userId") Long useId);
}