简介
Feign makes writing java http clients easier(声明式http客户端)官方文档
整合Feign
- 加依赖
<!--version由父工程定义-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 写注解
@EnableFeignClients
- 写配置
无
使用
package com.virgo.user.feignclient;
import com.virgo.entity.TblCar;
import com.virgo.user.configuration.GlobalFeignConfiguration;
import com.virgo.user.feignclient.fallbackFactory.LockCenterFeignClientFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @author zhaozha
* @date 2019/10/11 下午12:52
*/
@FeignClient(name = "lock-center", configuration = GlobalFeignConfiguration.class,fallbackFactory = LockCenterFeignClientFallbackFactory.class)
public interface LockCenterFeignClient {
// 自动构建http://lock-center/lock/test/{id}
@GetMapping("/lock/test/{id}")
TblCar findById(@PathVariable(value="id") Long id);
}
// Controller
...
private final LockCenterFeignClient lockCenterFeignClient;
...
TblCar tblCar = lockCenterFeignClient.findById(4000002L);
...
组成
| 接口 | 作用 | 默认值 |
|---|---|---|
| Feign.Builder | Feign的入口 | Feign.Builder |
| Client | Feign底层用什么去请求 | LoadBalancerFeignClient(整合Ribbon)/fengn.Client.Default(不整合Ribbon) |
| Contract | 契约,注解支持 | SpringMvcContract |
| Encoder | 编码器,用于将对象转换成HTTP请求消息体 | SpringEncoder |
| Decoder | 解码器,将响应消息体转换成对象 | ResponseEntityDecoder |
| Logger | 日志管理器 | Slf4jLogger |
| RequestInterceptor | 用于为每个请求添加通用逻辑 | 无 |
日志级别
| 级别 | 打印内容 |
|---|---|
| NONE(默认值) | 不记录任何日志 |
| BASIC | 仅记录请求的方法/URL/响应状态码/执行时间 |
| HEADERS | BASIC+请求和响应的header |
| FULL | 记录请求和响应的header/body/元数据 |
日志配置
-
细粒度代码
- yml
Feign日志级别设置(代码) logging: level: com.virgo.user.feignclient.LockCenterFeignClient: debug- 代码
package com.virgo.user.feignclient; import com.virgo.entity.TblCar; import com.virgo.user.configuration.GlobalFeignConfiguration; import com.virgo.user.feignclient.fallbackFactory.LockCenterFeignClientFallbackFactory; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; /** * @author zhaozha * @date 2019/10/11 下午12:52 */ @FeignClient(name = "lock-center", configuration = GlobalFeignConfiguration.class,fallbackFactory = LockCenterFeignClientFallbackFactory.class) public interface LockCenterFeignClient { @GetMapping("/lock/test/{id}") TblCar findById(@PathVariable(value="id") Long id); } GlobalFeignConfiguration.class package com.virgo.user.configuration; import feign.Logger; import org.springframework.context.annotation.Bean; /** * @author zhaozha * @date 2019/10/11 下午1:18 */ public class GlobalFeignConfiguration { @Bean public Logger.Level level(){ // 让feign打印所有请求的细节 return Logger.Level.FULL; } } -
细粒度配置
feign:
client:
config:
lock-center:
loggerLevel: FULL
- 全局代码
@EnableFeignClients(defaultConfiguration = GlobalFeignConfiguration.class)
- 全局配置
feign:
client:
config:
default:
loggerLevel: FULL
配置项
代码
| 配置项 | 作用 |
|---|---|
| Logger.Level | 指定日志级别 |
| Retryer | 指定重试策略 |
| ErrorDecoder | 指定错误解码器 |
| Request.Options | 超时时间 |
| Collection | 拦截器 |
| SetterFactory | Hystrix相关 |
配置
feign:
client:
config:
# 全局
default:
# 日志级别
loggerLevel:
# 连接超时时间
connectTimeout:
# 读取超时时间
readTimeout:
# 错误解码器
errorDecoder:
# 重试策略
retryer:
# 拦截器
requestInterceptors:
# 404错误码解码
decode404:
# 编码器
encoder:
# 解码器
decoder:
# 契约
contract:
继承
todo
多参数
@GetMapping("/lock/car/{carId}/user/{userId}")
TblCar findById(@PathVariable(value="carId") Long carId,@PathVariable(value="userId") Long userId);
脱离ribbon
@FeignClient(name="",url="")
feign & restTemplate
- 性能:restTemplate
- 可读性:feign
优化
feign:
httpclient:
# 让feign使用apache httpclient做请求;而不是默认的urlconnection
enabled: true
# feign的最大连接数
max-connections: 200
# feign单个路径的最大连接数
max-connections-per-route: 50
fallback & fallbackFactory
- fallback
// 1注解
@FeignClient(....,fallback=xxx.class)
// 2代码
package com.virgo.user.feignclient.fallback;
import com.virgo.entity.TblCar;
import com.virgo.user.feignclient.LockCenterFeignClient;
import org.springframework.stereotype.Component;
/**
* @author zhaozha
* @date 2019/10/16 下午3:36
*/
@Component
public class LockCenterFeignClientFallback implements LockCenterFeignClient {
@Override
public TblCar findById(Long id,Long userId) {
return TblCar.builder().level(1).build();
}
@Override
public TblCar testPost(String params) {
return null;
}
}
- fallbackFactory(强于fallback,可以打印异常)
// 1注解
@FeignClient(....,fallbackFactory=xxx.class)
// 2代码
package com.virgo.user.feignclient.fallbackFactory;
import com.virgo.entity.TblCar;
import com.virgo.user.feignclient.LockCenterFeignClient;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author zhaozha
* @date 2019/10/16 下午4:02
*/
@Component
@Slf4j
public class LockCenterFeignClientFallbackFactory implements FallbackFactory<LockCenterFeignClient> {
@Override
public LockCenterFeignClient create(Throwable throwable) {
return new LockCenterFeignClient() {
@Override
public TblCar findById(Long id,Long userId) {
log.info("限流/降级",throwable);
return TblCar.builder().level(1).build();
}
@Override
public TblCar testPost(String params) {
return null;
}
};
}
}