SpringCloud - Feign
Feign 入门
先看 RestTemplate 发起远程调用的代码:
String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
存在以下问题:
- 代码可读性差,编程体验不统一
- 参数复杂URL难以维护
Feign 是一个声明式的http 客户端,官方地址:https://github.com/OpenFeign/feign
其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题
使用入门:
1.引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.启动类开启注解
3.编写客户端
package cn.itcast.order.client;
import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient("userservice")
public interface UserClient {
/*
主要是使用SpringMVC的注解来声明远程调用:
1.服务名称:userservice
2.请求方式:Get
3.请求路径:/user/{id}
4.请求参数: Long id
5.返回值类型:User
*/
@GetMapping("/user/{id}")
User fingById(@PathVariable("id") Long id);
}
4.修改order-service
@Autowired
private UserClient userClient;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2.查询用户信息
User user = userClient.fingById(order.getUserId());
order.setUser(user);
// 3.返回
return order;
}
feign 中已经引入ribbon,因此默认也是已经支持负载均衡的:
Feign 支持自定义配置
Feign 运行自定义配置来覆盖默认配置,可以修改的配置如下:
一般我们需求配置的就是日志级别。默认为NONE
e.g: 更改日志方式一:
feign:
client:
config:
default: # 对所请求的全部微服务生效,也可指定具体微服务 比如uservice
logger-level: FULL
控制台日志:
09-09 11:13:10:320 DEBUG 15732 --- [nio-8080-exec-7] c.i.order.mapper.OrderMapper.findById : ==> Parameters: 101(Long)
09-09 11:13:10:331 DEBUG 15732 --- [nio-8080-exec-7] c.i.order.mapper.OrderMapper.findById : <== Total: 1
09-09 11:13:10:335 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] ---> GET http://userservice/user/1 HTTP/1.1
09-09 11:13:10:335 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] ---> END HTTP (0-byte body)
09-09 11:13:10:373 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] <--- HTTP/1.1 200 (36ms)
09-09 11:13:10:373 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] connection: keep-alive
09-09 11:13:10:373 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] content-type: application/json
09-09 11:13:10:373 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] date: Sat, 09 Sep 2023 03:13:10 GMT
09-09 11:13:10:373 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] keep-alive: timeout=60
09-09 11:13:10:373 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] transfer-encoding: chunked
09-09 11:13:10:373 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById]
09-09 11:13:10:374 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] {"id":1,"username":"柳岩","address":"湖南省衡阳市"}
09-09 11:13:10:374 DEBUG 15732 --- [nio-8080-exec-7] cn.itcast.order.client.UserClient : [UserClient#fingById] <--- END HTTP (59-byte body)
log.level 配置为BASIC 的效果:
09-09 11:20:57:735 DEBUG 4416 --- [nio-8080-exec-4] cn.itcast.order.client.UserClient : [UserClient#fingById] ---> GET http://userservice/user/1 HTTP/1.1
09-09 11:20:57:766 DEBUG 4416 --- [nio-8080-exec-4] cn.itcast.order.client.UserClient : [UserClient#fingById] <--- HTTP/1.1 200 (29ms)
更改配置方式二:
针对所有微服务调用生效:
针对具体微服务调用生效:
package cn.itcast.order.client;
import cn.itcast.order.config.DefaultFeignLClientConfig;
import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value= "userservice", configuration = DefaultFeignLClientConfig.class)
public interface UserClient {
@GetMapping("/user/{id}")
User fingById(@PathVariable("id") Long id);
}
logger.level 配置为 HEADERS 的效果:
09-09 11:27:17:292 DEBUG 9304 --- [nio-8080-exec-2] cn.itcast.order.client.UserClient : [UserClient#fingById] <--- HTTP/1.1 200 (29ms)
09-09 11:27:17:292 DEBUG 9304 --- [nio-8080-exec-2] cn.itcast.order.client.UserClient : [UserClient#fingById] connection: keep-alive
09-09 11:27:17:292 DEBUG 9304 --- [nio-8080-exec-2] cn.itcast.order.client.UserClient : [UserClient#fingById] content-type: application/json
09-09 11:27:17:292 DEBUG 9304 --- [nio-8080-exec-2] cn.itcast.order.client.UserClient : [UserClient#fingById] date: Sat, 09 Sep 2023 03:27:17 GMT
09-09 11:27:17:293 DEBUG 9304 --- [nio-8080-exec-2] cn.itcast.order.client.UserClient : [UserClient#fingById] keep-alive: timeout=60
09-09 11:27:17:293 DEBUG 9304 --- [nio-8080-exec-2] cn.itcast.order.client.UserClient : [UserClient#fingById] transfer-encoding: chunked
09-09 11:27:17:293 DEBUG 9304 --- [nio-8080-exec-2] cn.itcast.order.client.UserClient : [UserClient#fingById] <--- END HTTP (59-byte body)
Feign 性能优化
Feign 底层的客户端实现:
- URLConnection:默认实现,不支持连接池
- Apache HttpClient:支持连接池
- OKHttp: 支持连接池
因此优化Feign 的性能主要包括:
- 使用连接池代替默认的URLConnection
- 日志级别最好使用basic 或 none
修改Feign 底层客户端的实现步骤:
1.引入依赖:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
2.修改配置:
feign:
client:
config:
default: # 全部生效,也可指定具体uservice
logger-level: BASIC
httpclient:
enabled: true
max-connections: 200 # 最大连接数
max-connections-per-route: 50 # 每个路径的最大连接数
Feign - 最佳实践
方式一:继承
方式二:抽取,将FeignClient 抽取为独立的模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用
方式二案例:
1.新建feign-api发模块:
2.order-service 引入 feign-api 依赖:
3.order-service 启动类指定具体的FeignClient类或者 FeignClient所在的包(全部的FeiginClient)
//引入具体的FeignClient类
@EnableFeignClients(clients = UserClient.class)
/引入所有的FeignClient类
@EnableFeignClients(basePackages = "com.chuangzhou.client")
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/17689018.html