Feign
Feign是为了解决RestTemplate将URL请求卷入到开发业务的问题而设计的。
使用Feign,你可以针对一个服务创建一个接口,其中描述该服务的细节,然后就可以通过这个接口来对服务进行调用,而非用URL拼接的方式。
QuickStart#
导入#
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
启动类添加注解:
@EnableFeignClients
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
定义服务接口#
@FeignClient(name = "user-service") // 指定服务名
public interface UserClient {
@GetMapping("/user/{id}") // 以Controller类似的方式开发服务接口
User findById(@PathVariable("id") Integer id);
}
调用服务接口#
下面是使用userClient
与restTemplate
的对比,清爽多了:
-@Autowired
-private RestTemplate restTemplate;
+@Autowired
+private UserClient userClient;
public Order getOrderById(Integer id) {
Order order = repository.selectById(id);
- User user = restTemplate.getForObject("http://user-service/user/" + order.getUserId(), User.class);
+ User user = userClient.findById(order.getUserId());
order.setUser(user);
return order;
}
负载均衡#
使用RestTemplate
时我们可以在RestTemplate
Bean上加一个LoadBalance
注解,这样这个RestTemplate
发出的请求就具有了负载均衡能力,而Feign
不用做任何配置就已经有了负载均衡能力,也是使用Ribbon实现的。
自定义配置#
Feign提供如下自定义配置:
配置文件#
feign:
client:
config:
# 配置user-service的日志级别为HEADERS,即打印出请求响应的头信息
# 如果你想提供一些默认的全局配置,可以使用default
user-service:
logger-level: HEADERS
# 同时别忘了,将你的包的日志级别开成debug
logging:
level:
top:
yudoge: debug
打印出的日志:
Java代码#
public class FeignClientConfiguration {
@Bean
public Logger.Level feignLogLevel() {
return Logger.Level.FULL;
}
}
现在,你定义了一个Feign客户端配置类,如果你期望这个配置类里的配置作用于全局,就在全局的@EnableFeignClients
注解上添加
@SpringBootApplication
// 指定配置类
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
如果你想要它应用在特定的服务上,就在服务的@FeignClient
上添加:
@FeignClient(name = "user-service", configuration = FeignClientConfiguration.class)
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Integer id);
}
日志对于Feign性能的影响较大,能不开就不开
Feign替换客户端实现#
Feign提供三种客户端实现:
- URLConnection:默认实现,不支持连接池
- Apache HttpClient:支持连接池
- OKHttp:支持连接池
下面替换客户端实现到HttpClient
导入依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
配置连接池
feign:
client:
config:
default:
logger-level: BASIC
httpclient:
enabled: true
max-connections: 200
max-connections-per-route: 50
实际上,我发现Feign默认已经带这个httpclient依赖了,而且它默认也是开启状态,可能现在Feign的默认客户端就是它吧,所以说我们不配置应该也是一样的。
Feign最佳实践#
现在有一个问题,我们把UserClient
和User
这个实体类定义在了order-service
微服务中,因为它要使用user-service
,这看起来理所当然。但当我们有另一个服务业要使用user-service
时,我们就得将这一套相同的东西再在另一个微服务中定义一次。
再有一个问题就是,我们定义的FeignClient和要调用的微服务的Controller极其类似:
服务消费者中的Client:
我们应该消除这两种重复
消除消费者Client和提供者Controller中的方法签名重复#
在一个公共项目中提供一个父接口,让客户端的Client直接继承这个接口,提供者直接实现这个接口
问题:消费者和提供者紧耦合到同一个API,并且在SpringMVC中,方法注解信息不能继承,所以说这些东西你还得重新写。
消除使用同一个服务的多个Client端中的代码重复#
在一个公共项目中提供客户端需要的Client
、Pojo以及客户端配置,让需要的用户直接引入后使用
总结#
- Feign相比RestTemplate,使用Client接口方式编程,让我们的代码更加优雅
- Feign自带使用Ribbon的负载均衡
- Feign提供一些自定义的配置,最常用的就是配置日志
- Feign底层http请求客户端可以被替换
- 我们可以通过单独将多个消费者都需要的Client、配置和Pojo放在单独的项目中以消除代码在多个服务消费者间的重复编写
作者:Yudoge
出处:https://www.cnblogs.com/lilpig/p/16556803.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
欢迎按协议规定转载,方便的话,发个站内信给我嗷~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)