SpringCloud-04 OpenFeign服务调用与负载均衡
OpenFeign是一个声明式、模板化的HTTP客户端,它简化了在Java应用程序中调用RESTful API的过程。OpenFeign是Netflix开发的一个开源项目,它构建在Feign的基础上,为开发者提供了更加简单、灵活的方式来实现HTTP请求。OpenFeign的特点包括:
前面在使用SpringCloud LoadBalancer+RestTemplate时,利用RestTemplate对http请求的封装处理形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,OpenFeign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在OpenFeign的实现下,我们只需创建一个接口并使用注解的方式来配置它(在一个微服务接口上面标注一个@FeignClient注解即可),即可完成对服务提供方的接口绑定,统一对外暴露可以被调用的接口方法,大大简化和降低了调用客户端的开发量,也即由服务提供者给出调用接口清单,消费者直接通过OpenFeign调用即可。
OpenFeign同时还集成SpringCloud LoadBalancer,可以在使用OpenFeign时提供Http客户端的负载均衡,也可以集成阿里巴巴Sentinel来提供熔断、降级等功能。而与SpringCloud LoadBalancer不同的是,通过OpenFeign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。
在一个接口上添加@FeugnClient注解即可
OpenFeign使用:
1.新建一个Module,添加pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.dc.cloud</groupId>
<artifactId>cloud2024</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>cloud-consumer-feign-order80</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--openfeign-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-openfeign</artifactId>-->
<!-- <version></version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.1.3</version>
</dependency>
<!--SpringCloud consul discovery-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- 引入自己定义的api通用包 -->
<dependency>
<groupId>com.dc.cloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--web + actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--hutool-all-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!--fastjson2-->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.修改yml配置文件
server:
port: 80
spring:
application:
name: cloud-consumer-openfeign-order
####Spring Cloud Consul for Service Discovery
cloud:
consul:
host: localhost
port: 8500
discovery:
prefer-ip-address: true #优先使用服务ip进行注册
service-name: ${spring.application.name}
3.主启动类
@SpringBootApplication
@EnableDiscoveryClient //该注解用于向使用consul为注册中心时注册服务
@EnableFeignClients//启用feign客户端,定义服务+绑定接口,以声明式的方法优雅而简单的实现服务调用
public class MainOpenFeign80 {
public static void main(String[] args) {
SpringApplication.run(MainOpenFeign80.class,args);
}
}
4.修改cloud-api-commons通用模块
//在通用模块端口也需添加pom依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.1.3</version>
</dependency>
//新建接口
@FeignClient("cloud-payment-service")
public interface PayFeignApi {
@PostMapping(value="/pay/add")
public ResultData addPay(@RequestBody payDTO paydto);
@GetMapping(value="/pay/get/{id}")
public ResultData getPayInfo(@PathVariable("id") Integer id);
@GetMapping(value="/pay/get/info")
public String mylb();
}
//在cloud-consumer-feign-order80模块新增controller
@RestController
public class OrderController {
@Resource
private PayFeignApi payFeignApi;
@PostMapping(value="/feign/pay/add")
public ResultData addOrder(@RequestBody payDTO payDTO){
System.out.println("新增订单操作");
ResultData resultData=payFeignApi.addPay(payDTO);
return resultData;
}
@GetMapping(value="/feign/pay/get/{id}")
public ResultData getPayInfo(@PathVariable("id")Integer id){
System.out.println("按照id查看订单支付流水");
ResultData resultData=payFeignApi.getPayInfo(id);
return resultData;
}
@GetMapping(value="/feign/pay/mylb")
public String mylb(){
return payFeignApi.mylb();
}
}
OpenFeign高级特性
1.超时控制
在使用OpenFeign进行服务调用时,可以设置超时控制来限制请求的最大执行时间。OpenFeign提供了两种设置超时的方式:全局超时设置和针对特定请求的超时设置。
默认等待60秒,超过60秒拿不到查询结果就会报错
//全局设置
server:
port: 80
spring:
application:
name: cloud-consumer-openfeign-order
cloud:
consul:
host: localhost
port: 8500
discovery:
prefer-ip-address: true #优先使用服务ip进行注册
service-name: ${spring.application.name}
openfeign:
client:
config:
default:
#连接超时时间
connectTimeout: 3000
#读取超时时间
readTimeout: 3000
//局部配置会覆盖全局配置
server:
port: 80
spring:
application:
name: cloud-consumer-openfeign-order
cloud:
consul:
host: localhost
port: 8500
discovery:
prefer-ip-address: true #优先使用服务ip进行注册
service-name: ${spring.application.name}
openfeign:
client:
config:
default:
#连接超时时间
connectTimeout: 3000 #3秒
#读取超时时间
readTimeout: 3000
cloud-payment-service:
#连接超时时间
connectTimeout: 10000
#读取超时时间
readTimeout: 10000
2.重试机制
重试机制默认关闭(只会在规定时间调用一次)
//在80端口添加配置类OpenFeignConfig类
@Configuration
public class OpenFeignConfig {
@Bean
public Retryer myRetryer() {
// return Retryer.NEVER_RETRY;//默认:不会重试
return new Retryer.Default(100,1,4);//初始间隔时间 重试间隔时间1s 最大重试次数
}
}
3.OpenFeign中的http client
如果不做特殊配置,OpenFeign默认使用JDK自带的HttpURLConnection发送HTTP请求,由于默认HttpURLConnection没有连接池、性能和效率比较低,如果采用默认,性能上不是最好的。
//在OPenFeign80端口添加pom依赖
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3</version>
</dependency>
<!-- feign-hc5-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hc5</artifactId>
<version>13.1</version>
</dependency>
//修改yml文件
httpclient:
hc5:
enabled: true
4.请求/响应压缩功能
Spring Cloud OpenFeign支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。
//yml文件修改
server:
port: 80
spring:
application:
name: cloud-consumer-openfeign-order
cloud:
consul:
host: localhost
port: 8500
discovery:
prefer-ip-address: true #优先使用服务ip进行注册
service-name: ${spring.application.name}
openfeign:
client:
config:
default:
#连接超时时间
connectTimeout: 3000 #3秒
#读取超时时间
readTimeout: 3000
cloud-payment-service:
#连接超时时间
connectTimeout: 10000
#读取超时时间
readTimeout: 10000
httpclient:
hc5:
enabled: true
compression:
request:
enabled: true
min-request-size: 2048 #最小触发压缩的大小
mime-types: text/xml,application/xml,application/json #触发压缩数据类型
response:
enabled: true
5.日志打印功能
Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节,就是对Feign接口的调用情况进行监控和输出。
NONE:默认的,不显示任何日志;
BASIC:仅记录请求方法、URL、响应状态码及执行时间;
HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息;
FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。
//修改OpenFeignConfig类
@Configuration
public class OpenFeignConfig {
@Bean
public Retryer myRetryer() {
return Retryer.NEVER_RETRY;//默认:不会重试
// return new Retryer.Default(100,1,4);//初始间隔时间 重试间隔时间1s 最大重试次数
}
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
//yml文件修改
server:
port: 80
spring:
application:
name: cloud-consumer-openfeign-order
cloud:
consul:
host: localhost
port: 8500
discovery:
prefer-ip-address: true #优先使用服务ip进行注册
service-name: ${spring.application.name}
openfeign:
client:
config:
default:
#连接超时时间
connectTimeout: 3000 #3秒
#读取超时时间
readTimeout: 3000
cloud-payment-service:
#连接超时时间
connectTimeout: 10000
#读取超时时间
readTimeout: 10000
httpclient:
hc5:
enabled: true
compression:
request:
enabled: true
min-request-size: 2048 #最小触发压缩的大小
mime-types: text/xml,application/xml,application/json #触发压缩数据类型
response:
enabled: true
# feign日志以什么级别监控哪个接口
logging:
level:
com:
dc:
cloud:
apis:
PayFeignApi: debug
压缩
三次重试