SpringCloud(3)— Http客户端Feign
一 RestTemplate存在的问题
1.代码可读性差,编程体验不统一
@Autowired
private RestTemplate restTemplate;
@GetMapping("/{id}")
public Order get(@PathVariable Integer id){
Order order = orderService.getById(id);
//String url="http://localhost:8082/user/"+order.getUserId();
String url="http://alibaba-user/user/"+order.getUserId();
User user = restTemplate.getForObject(url, User.class);
order.setUser(user);
return order;
}
2.参数复杂的URL维护困难
二 Feign的使用
1.Feign的介绍
Feign是一种声明式的Http客户端,可以更加优雅的实现Http发送,从而解决以上问题。
2.使用Feign
1.引入Feign的Maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
或者在使用Spring initializr 创建项目时直接勾选
2.开启Feign
在 服务的启动类中添加 @EnableFeignClients 注解开启Feign
@SpringBootApplication
@EnableFeignClients
public class AlibabaOrderApplication {
public static void main(String[] args) {
SpringApplication.run(AlibabaOrderApplication.class, args);
}
}
3.定义Feign接口
@FeignClient("alibaba-user")
public interface UserFeign {
/**
* 定义请求接口
* @FeignClient 服务名称
* @param id userId
* @return 返回对象
*/
@GetMapping("/{id}")
User findById(@PathVariable Integer id);
}
Feign主要是基于SpringMVC的注解来申明远程调用的信息
@Autowired
private IUserClientFeign userClientFeign;
@GetMapping("/{id}")
public Order get(@PathVariable Integer id){
Order order = orderService.getById(id);
User user=userClientFeign.findById(order.getUserId());
order.setUser(user);
return order;
}
4.Feign的自定义配置
1.日志级别的配置
创建Feign的配置类
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
// 指定 Feign 的输出日志级别
return Logger.Level.FULL;
}
}
或者在项目配置文件中直接配置
feign:
client:
config:
# 此处为 default 时,输出全部的服务日志,如果想看指定服务的日志,则只需要将 default 修改为服务名即可
default:
loggerLevel: FULL
指定项目配置文件中的logger的输出范围
logging:
level:
# 指定包下或指定类的日志输出级别
com.shawn.order: debug
重新运行项目,输出效果如下:
可将日志级别的配置放在 Nacos 统一配置管理中心,方便根据情况调整日志级别
3.Feign的性能优化
1.底层实现
1.URLConnection: 默认实现,不支持连接池
2.Apache HttpClinet: 支持连接池
3.OKHttp: 支持连接池
2.性能优化
1.使用连接池代替URLConnection
2.日志级别,最好使用Basic或None
3.性能优化-配置连接池
1.使用HttpClient
引入 HttpClient 依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
配置相关参数
feign:
client:
config:
default:
loggerLevel: FULL
httpclient:
enabled: true # 允许Feign使用Apache HTTP客户端。
max-connections: 200 # 最大连接数
connection-timeout: 2000 # 超时时间
max-connections-per-route: 50 # 单个路由最大连接数
disable-ssl-validation: false # 禁用SSL验证
connection-timer-repeat: 3000 # 连接重试计时
follow-redirects: true # 遵循重定向
time-to-live: 900 # 生存时间
time-to-live-unit: seconds # 生存时间单位
三 Feign的最佳实践
1.继承
给消费者的FeignClient和提供者的Controller定义统一的父接口作为标准。
以上方式不推荐,应为它们紧耦合。且对SpringMVC不适用,控制器中的方法参数无法继承下来,只能重新实现。
2.抽取
将FeignClient抽取为独立模块,并且把接口相关的POJO,默认的Feign配置都放在这个模块中,提供给所有消费者使用。
针对Feign的包无法被扫描到时,可使用一下两种方案