简述
OpenFeign
是一个声明式的web服务客户端,只需创建一个Rest接口并在该接口上添加注解@FeignClient
即可
其本质上就是当前微服务之间调用的事实标准
OpenFeign
同时还集成了Spring Cloud LoadBalancer
,可以在使用OpenFeign
时提供Http客户端的负载均衡,也可以基础阿里巴巴Sentinel
来提供熔断、降级等功能
通用步骤
总流程图
服务提供者
接口控制器
package com.xlyo.openfeignlearnprovider.controller;
import jakarta.annotation.PostConstruct;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/pay")
public class PayController {
private static final List<String> payList = new ArrayList<>();
@PostConstruct
public void init() {
payList.addAll(List.of("支付宝", "微信", "银联"));
}
@GetMapping("/list")
public List<String> getPayList() {
return payList;
}
@PostMapping("/add")
public String add(@RequestParam("item") String item) {
payList.add(item);
return "ok";
}
}
公共依赖
从服务提供者抽取供其它微服务调用的接口
pom依赖
这里只放一些相关的代码
<properties>
<spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
<dependencies>
<!-- OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Maven私服发布管理 -->
<distributionManagement>
<repository>
<id>xlyo-cloud</id>
<url>http://47.116.120.48:45502/repository/xlyo-cloud/</url>
</repository>
</distributionManagement>
<!-- 构建 -->
<build>
<plugins>
<!-- 打包Jar插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.1</version>
</plugin>
<!--发布代码Jar插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<!--发布源码插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
抽取接口
package com.xlyo.openfeignlearncommon;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Component
@FeignClient(name = "pay-service", url = "http://localhost:8082")
public interface PayFeignApi {
@GetMapping("/pay/list")
List<String> getPayList();
@PostMapping("/pay/add")
String add(@RequestParam("item") String item);
}
@Component
用于注册到spring
的IOC
容器中
@FeignClient
服务消费者
pom依赖
这里只放一些相关的代码
<properties>
<spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
<!-- Maven私服 -->
<repositories>
<repository>
<id>xlyo-cloud</id>
<url>http://47.116.120.48:45502/repository/xlyo-cloud/</url>
</repository>
</repositories>
<dependencies>
<!-- 引用私服上的Jar包 - 公共依赖 -->
<dependency>
<groupId>com.xlyo</groupId>
<artifactId>open-feign-learn-common</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
主启动类
package com.xlyo.openfeignlearnconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients("com.xlyo.openfeignlearncommon")
@SpringBootApplication
public class OpenFeignLearnConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(OpenFeignLearnConsumerApplication.class, args);
}
}
@EnableFeignClients
需要指定OpenFeign
的扫描包路径
接口控制器
package com.xlyo.openfeignlearnconsumer.controller;
import com.xlyo.openfeignlearncommon.PayFeignApi;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/managePay")
public class ManagePayController {
@Resource
private PayFeignApi payService;
@GetMapping("/list")
public List<String> list() {
return payService.getPayList();
}
@GetMapping("/add")
public String add(String item) {
return payService.add(item);
}
}
测试
GET http://localhost:8081/managePay/add?item=%E9%BB%91%E9%87%91%E5%8D%A1
现在通过服务提供者看看上述调用有没有成功添加数据
GET http://localhost:8082/pay/list
超时控制
OpenFeign
的默认超时时间是60秒,超时直接抛异常
我们可以配置其超时时间,其有2个超时时间
connectTimeout:连接超时时间
readTimeout:请求处理超时时间
全局配置
spring:
cloud:
openfeign:
client:
config:
default:
connect-timeout: 3000 # 连接超时时间,这里为3秒
read-timeout: 3000 # 请求处理超时时间,这里为3秒
指定配置
单个服务调用的超时配置
如果同时指定default,则单个配置会覆盖默认/全局配置
spring:
cloud:
openfeign:
client:
config:
pay-service: # 这里的名字要和公共依赖中接口的名字一致
connect-timeout: 5000 # 连接超时时间,这里为5秒
read-timeout: 5000 # 请求处理超时时间,这里为5秒
上述的pay-service
与公共依赖@FeignClient
的name相同
@FeignClient(name = "pay-service", url = "http://localhost:8082")
public interface PayFeignApi {
...
}
重试机制
默认的重试是关闭的,其默认值为Retryer.NEVER_RETRY
要开启就需要进行手动配置
package com.xlyo.openfeignlearnconsumer.config;
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfiguration {
/**
* 设置Feign的重试策略
*/
@Bean
public Retryer feignRetryer() {
// return Retryer.NEVER_RETRY; // 默认禁用重试
// 初始间隔100ms,重试最大间隔1s,最大重试次数3
return new Retryer.Default(100, 1, 3);
}
}
性能优化
OpenFiegn
默认使用JDK自带的HttpURLConnection
发送HTTP请求,其没有连接池,性能和效率低下
需要使用Apache HttpClient5进行替换
<!-- OpenFeign替换HttpClient5 -->
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 -->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-hc5 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hc5</artifactId>
<version>13.2.1</version>
</dependency>
spring:
cloud:
openfeign:
httpclient:
hc5:
enabled: true
请求响应压缩
对请求和响应的内容进行压缩,以缩减少通信过程中的性能损耗
spring:
cloud:
openfeign:
compression:
request:
enabled: true # 开启请求压缩
mime-types: text/xml,application/xml,application/json # 触发请求压缩的类型
min-request-size: 2048 # 最小触发请求压缩的大小
response:
enabled: true # 开启响应压缩
日志打印
通过调整日志级别,对其接口调用情况进行监控和输出
NONE:默认,不显示如何日志;
BASIC:仅记录请求方法、URL、响应状态码和执行时间;
HEADERS:除了
BASIC
中的信息外,还有请求和响应头的信息;FULL:除了
HEADERS
中的信息外,还有请求和响应头的正文及元数据;
package com.xlyo.openfeignlearnconsumer.config;
import feign.Logger;
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfiguration {
/**
* 设置Feign日志级别
*/
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
logging:
level:
com: # 全包名
xlyo:
openfeignlearncommon:
PayFeignApi: DEBUG # 设置要监控的公共依赖接口