OpenFeign简介
OpenFeign是一种声明式、模板化的HTTP客户端(仅在Application Client中使用)。声明式调用是指,就像调用本地方法一样调用远程方法,无需感知操作远程http请求。
OpenFeign和Feign的区别
Feign是Spring Cloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。
OpenFeign 是 Spring Cloud 对 Feign 的二次封装,它具有 Feign 的所有功能,并在 Feign 的基础上增加了对 Spring MVC 注解的支持,例如 @RequestMapping、@GetMapping 和 @PostMapping 等。
OpenFeign使用
创建一个父项目,引入pom文件,通过dependencyManagement
统一管理依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.parent</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<spring.boot.version>2.7.4</spring.boot.version>
<spring-cloud.version>2021.0.3</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
创建服务提供方项目模块,引入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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.parent</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
</project>
bootstrap.yaml
配置
server:
port: 8081
spring:
application:
name: provide
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: 6ce494ed-79a0-4c58-addf-cf66aa8f32b8
config:
server-addr: localhost:8848
file-extension: yaml
namespace: 6ce494ed-79a0-4c58-addf-cf66aa8f32b8
profiles:
active: dev
启动类
@SpringBootApplication
@EnableDiscoveryClient
public class ProvideApplication {
public static void main(String[] args) {
SpringApplication.run(ProvideApplication.class, args);
}
}
提供接口
@RestController
public class TestController {
@Value("${version}")
private String version;
@GetMapping("/test")
public String test() {
return version;
}
}
创建服务消费方项目模块,引入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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.parent</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com</groupId>
<artifactId>consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>consumer</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
</project>
bootstrap.yaml
配置
server:
port: 8082
spring:
application:
name: consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: 6ce494ed-79a0-4c58-addf-cf66aa8f32b8
config:
server-addr: localhost:8848
file-extension: yaml
namespace: 6ce494ed-79a0-4c58-addf-cf66aa8f32b8
profiles:
active: dev
启动类
@SpringBootApplication
@EnableFeignClients("com.consumer.feign")
@EnableDiscoveryClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
声明feign接口,name/value属性,这两个的作用是一样的,指定的是调用服务的微服务名称,互为对方的别名。url属性指定调用服务的全路径,经常用于本地测试。如果同时指定name/value和url属性,则以url属性为准,name/value属性指定的值便当做客户端的名称。
@FeignClient(value = "provide")
public interface TestFeign {
@GetMapping("/test")
String test();
}
外部调用
@RestController
public class TestController {
@Autowired
private TestFeign testFeign;
@GetMapping("/consumer/test")
public String test() {
return testFeign.test();
}
}
启动本地nacos、provide、consumer服务
访问http://localhost:8082/consumer/test
OpenFeign超时时间设置
默认不生效连接超时时间10秒、读超时时间60秒,源码在feign.Request.Options#Options()这个方法中
public Options() {
this(10, TimeUnit.SECONDS, 60, TimeUnit.SECONDS, true);
}
超时时间配置
feign:
client:
config:
## default设置的全局超时时间,指定服务名称可以设置单个服务的超时时间
default:
connectTimeout: 5000
readTimeout: 5000S
## 为serviceA这个服务单独配置超时时间
serviceA:
connectTimeout: 10000
readTimeout: 10000