1.Feign概述
Feign是Spring Cloud提供的声明式、模板化的HTTP客户端, 它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可。
Spring Cloud集成Feign并对其进行了增强,使Feign支持了Spring MVC注解;Feign默认集成了Ribbon,所以Fegin默认就实现了负载均衡的效果。
(ribbon+restTemplate)+优化=feign
2.Feign入门案例
(1)创建服务提供者provider
①创建工程
②application.yml
server:
port: 9090
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.209.129:8848
application:
name: feign-provider
(2)创建feign接口
①创建工程 :feign_inference
②pom.xml
<dependencies>
<!--Spring Cloud OpenFeign Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.bjpowernode</groupId>
<artifactId>springcloud_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
③feign接口
//@FeignClient("服务名")
@FeignClient(value="sentinel-provider",fallbackFactory = UserFeignFallback.class)
@RequestMapping(value = "/provider")
public interface UserFeign {
@RequestMapping(value = "/getUserById/{id}")
public User getUserById(@PathVariable(value="id") Integer id);
}
(3)创建服务消费者consumer
①创建工程:feign_consumer
②pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.bjpowernode</groupId>
<artifactId>springcloud_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--feign接口-->
<dependency>
<groupId>com.bjpowernode</groupId>
<artifactId>feign_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
③ application.yml
server:
port: 80
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.209.129:8848
application:
name: feign-consumer
④Controller
@RestController
@RequestMapping(value = "/consumer")
public class ConsumerController {
@Autowired
private UserFeign userFeign;
@RequestMapping(value = "/getUserById/{id}")
public User getUserById(@PathVariable Integer id) {
return userFeign.getUserById(id);
}
}
⑤APP
@SpringBootApplication
@EnableDiscoveryClient
//@EnableFeignClients(basePackages = "com.bjpowernode.feign")
@EnableFeignClients//开启feign接口扫描
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class);
}
}
⑥测试
3.Feign的原理
(1)将Feign接口注入到Spring容器中去
@EnableFeignClients注解开启Feign扫描,先调用FeignClientsRegistrar.registerFeignClients()方法扫描
@FeignClient注解的接口,再将这些接口注入到Spring IOC容器中,方便后续被调用。
(2)为接口的方法创建RequestTemplate
SynchronousMethodHandler.invoke():
当定义的的Feign接口中的方法被调用时,通过JDK的代理方式为Feign接口生成了一个动态代理类,当生成代理时,Feign会为每个接口方法创建一个RequestTemplate。该对象封装了HTTP请求需要的全部信息,如请url、参数,请求方式等信息都是在这个过程中确定的。
(3)发出请求
SynchronousMethodHandler.executeAndDecode():
代理类会通过RequestTemplate创建Request,然后client(URLConnetct、HttpClient、OkHttp)使用Request发送请求
4.Feign接口传参
传参方式:
-
restful风格:
feign接口:@PathVarible
【拼接restful形式的url】
-
?传参
feign接口:@RequestParam
【拼接?形式的url】
-
pojo参数
provider: @RequestBody User user
【获取请求体中的json串】
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
return userService.getUserById(id);//restful传参
}
@RequestMapping("/deleteUserById")
public User deleteUserById(Integer id) {
return userService.deleteUserById(id);//?传参
}
@RequestMapping("/addUser")
User addUser(@RequestBody User user){
return userService.addUser(user);//pojo
}
5.Feign的优化
(1)开启feign日志
①feign的日志级别
配置Feign的日志Feign有四种日志级别:
NONE【性能最佳,适用于生产】:不记录任何日志(默认值)
BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间
HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。
feign:
client:
config:
default:
loggerLevel: full
logging:
level:
com.bjpowernode.feign: debug
②测试
(2)feign超时
方式一:
feign:
client:
config:
feign-provider:
ConnectTimeout: 5000 #请求连接的超时时间
ReadTimeout: 5000 #请求处理的超时时间
方式二:
ribbon:
ConnectTimeout: 5000 #请求连接的超时时间
ReadTimeout: 5000 #请求处理的超时时间
(3)http连接池
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
(4)gzip压缩
①介绍:gzip是一种数据格式,采用deflate算法压缩date;gzip是一种流行的文件压缩算法,应用十分广泛,尤其是在linux平台
②能力:压缩一个纯文本文件时,大约可以减少70%以上的文件大小
③作用:节省流量,改善用户体验;Gzip与搜索引擎的抓取工具有着更好的关系
项目中启用gzip压缩:
server:
port: 80
compression:
enabled: true