1.Feign的组成
接口 | 作用 | 默认值 |
---|---|---|
Feign.Builder | Feign的入口 | Feign.Bui |
Client | Feign底层用什么去请求 | 和Ribbon配置时:LoadBalancerFeignclient <br />不和Ribbon配置时feign.Client.Default |
Contract | 契约,注解支持 | SpringMvcContract |
Encoder | 编码器,用于将对象转换成HTTP请求消息体 | SpringEncoder |
Decoder | 解码器,将相应消息转换成对象 | ResponseEntityDecoder |
Logger | 日志管理器 | Slf4jLogger |
RequestInterceptor | 用于为每个请求添加通用逻辑 | 无 |
2.细粒度配置Feign
使用自定义Feign
的日志级别来做事例
java
代码方式:
日志级别 | 打印的内容 |
---|---|
NONE | 不打印日志 |
BASIC | 请求方法,URL,响应状态码和执行时间 |
HEADERS | 记录BASIC级别的基础上,记录请求和响应的header |
FULL | 记录请求和响应的header,body和元数据 |
只需要在@FeignClient
的configuration
属性上面配置该客服端的Feign
配置即可
FeignClient
@FeignClient(name = "user-center", path = "/users", configuration = FeignClientConfiguration.class)
//@FeignClient(name = "user-center", path = "/users")
public interface UserCenterClient {
@GetMapping("/{id}")
UserDTO findById(@PathVariable Integer id);
}
FeignConfiguration
,这里注意和Ribbon
一样不能让SpringBoot
的@ComponentScan
扫描到该Bean
,不然会导致父子上下文重叠,变成全局配置 !!!
/**
* @author hj
* 2019-08-08 10:13
* 不能加@Configuration注解,加了则要挪到SpringBoot#@ComponentScan注解扫描之外,避免父子上下文的重复扫描
*/
public class FeignClientConfiguration {
@Bean
public Logger.Level level() {
//将feign的日志级别设置为full (none/basic/headers)
return Logger.Level.FULL;
}
}
配置的方式:
feign.client.config.<serviceName>.loggerLevel
logging:
level:
com.hujing.contentcenter.service.consumer.UserCenterClient: debug
#配置方式开启feign的日志功能,依赖logging.level 为debug
feign:
client:
config:
user-center:
loggerLevel: full
3.全局的feign
配置
Java代码方式:
直接使用defaultConfgiuration
属性指向配置类即可
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
配置方式:
将细粒度配置的服务名称换成 default
即可
logging:
level:
com.hujing.contentcenter.service.consumer.UserCenterClient: debug
#配置方式开启feign的日志功能,依赖logging.level 为debug
feign:
client:
config:
default:
loggerLevel: full
4.feign
能配置的配置项
java代码配置:
配置项 | 作用 |
---|---|
Logger.Level | 日志级别 |
Retryer | 重试策略 |
ErrorDecoder | 错误解码器 |
Request.Options | 超时时间 |
Collection<RequestInterceptor> | 拦截器 |
SetterFactory | 设置hystrix属性 |
配置属性支持的配置项:
见FeignClientConfiguration
类即可
5.关于feign
的继承的考虑
由于在服务消费方使用feign
进行消费,代码和提供方的controller
一致,那么可以提取出公共接口,让提供方controller
实现,让feign
继承
- 优点 : 方便开发,对代码紧耦合不太关注的
- 缺点:服务之间依赖相同的公共
api
模块,和微服务背道而驰
6.对于feign
的多参数请求
对于如此的feignClient
方法,直接使用会报错
@GetMapping("/q")
UserDTO q(UserDTO userDTO);
exception stack trace:
Request processing failed; nested exception is feign.FeignException$MethodNotAllowed: status 405 reading UserCenterClient#q(UserDTO)
如何解决?
在参数实体上面加上@SpringQueryMap
注解即可,还有其他方式参考博客
@GetMapping("/q")
UserDTO q(@SpringQueryMap UserDTO userDTO);
7.feign
的性能优化
1.连接方式
feign
底层默认使用的连接方式是HttpUrlConnection
,没有连接池的提供
使用HttpClient/OkHttp
代替HttpUrlConnection
- 引入依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
- 配置
feign:
httpclient:
enabled: true
max-connections: 200 #最大连接数
max-connections-per-route: 50 #单路径最大连接数