OpenFeign的使用
# OpenFeign的使用
# 声明式的服务间调用
使用SpringCloud LoadBalancer+RestTemplate时,利用RestTemplate对http请求的封装处理形成了一套模版化的调用方法。
但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,但这样的调用通常需要编写大量的样板代码,如构建 HTTP 请求、处理响应等。例如,使用 RestTemplate
手动构建请求和处理响应的代码可能非常冗长,而使用 OpenFeign 只需几行注解即可完成相同的功能。
// 传统方式
ResponseEntity<String> response = restTemplate.getForEntity("http://your-service-name/endpoint", String.class);
String result = response.getBody();
2
3
这样的调用数量上来后,会特别繁琐与麻烦。
为了解决这个问题,OpenFeign
出现了, 它通过声明式接口和注解
,自动生成这些代码,大大减少了开发工作量。
在OpenFeign的实现下,我们只需创建一个接口并使用注解的方式来配置它(在一个微服务接口上面标注一个@FeignClient注解即可),即可完成对服务提供方的接口绑定,统一对外暴露可以被调用的接口方法,大大简化和降低了调用客户端的开发量,也即由服务提供者给出调用接口清单,消费者直接通过OpenFeign调用即可。
// OpenFeign 方式
@FeignClient(name = "your-service-name")
public interface YourServiceClient {
@GetMapping("/endpoint")
String callService();
}
2
3
4
5
6
# 它的特点
OpenFeign除了简化服务间的调用外,它还有以下几个优势:
集成服务发现和负载均衡:
- 与 Spring Cloud 的服务发现组件和负载均衡组件无缝集成,自动处理服务发现和负载均衡。
- 提高了系统的可维护性和灵活性。
断路器支持:
- 与 Hystrix 集成,提供断路器功能,增强了系统的稳定性和容错能力。
可扩展性:
- 支持自定义编码器、解码器、错误处理器等,满足不同业务场景的需求。
但,在使用OpenFeign的时候请注意——性能开销
,这个问题。
- 由于 OpenFeign 是基于注解和接口的动态代理实现,可能会引入一定的性能开销。
- 在高并发场景下,需要注意性能调优。
# 总结
Spring Cloud OpenFeign 是一个强大的声明式 HTTP 客户端,它简化了微服务之间的调用,提供了服务发现、负载均衡和断路器等功能。通过简单的接口定义和注解,开发者可以更加专注于业务逻辑,而无需关心底层的 HTTP 请求细节。
# 相关资料和文档
SpringCloud OpenFeign官网:
# 快速上手
SpringCloud OpenFeign官网特性与使用说明 (opens new window)
- https://docs.spring.io/spring-cloud-openfeign/reference/
SpringCloud OpenFeign官网首页介绍 (opens new window)
- https://spring.io/projects/spring-cloud-openfeign#learn
# 上手步骤
注意,OpenFeign,需要跟 服务注册组件一起使用,比如consul或者nacos等。
第一步:引入对应pom坐标,官网的对应说明如下:
To include Feign in your project use the starter with group
org.springframework.cloud
and artifact idspring-cloud-starter-openfeign
.
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2
3
4
5
第二步:修改配置文件,让服务注册中心
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}
2
3
4
5
6
7
8
9
10
11
12
13
14
第三步:在主类或配置类中添加注解@EnableFeignClients(需要开放接口给其他服务调用的微服务),开启feign,启用服务间的发现。
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2
3
4
5
6
7
8
9
第四步:将之前的接口进行抽象添加注解,这些接口可以单独放在一个module中,也可以就在原有module中。这一步也成为定义Feign客户端。
// 定义 Feign 客户端
@FeignClient(name = "your-service-name")
public interface YourServiceClient {
@GetMapping("/endpoint")
String callService();
}
2
3
4
5
6
your-service-name,就是你注册到服务中心的微服务名称,下方的接口callService()
,就是your-service-name-微服务中对应的接口,请注意接口对应的返回值也要一致。
到此,OpenFeign实现服务间的调用全部完成。
在需要的服务中注入并使用 Feign 客户端,即可调用其他微服务接口。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class YourService {
@Autowired
private UserServiceClient userServiceClient;
public User getUserById(Long id) {
return userServiceClient.getUser(id);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
最后提示,为了更好的使用,可以将以上第四步中的接口,放到一个公共module中,从而达到更高效的利用率。
# 原理探究
OpenFeign 的实现原理主要包括以下几个方面:动态代理、注解解析、HTTP 请求构建和发送、以及响应处理。
# 1. 动态代理
OpenFeign 使用 Java 的动态代理机制来生成接口的实现类。当开发者定义了一个带有 @FeignClient
注解的接口时,OpenFeign 会为这个接口生成一个代理类。这个代理类负责处理实际的 HTTP 请求和响应。
# 2. 注解解析
OpenFeign 通过解析接口上的注解来确定 HTTP 请求的详细信息,包括请求方法、URL、请求参数等。常用的注解包括:
@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
等,用于指定 HTTP 方法。@PathVariable
、@RequestParam
、@RequestBody
等,用于指定请求参数的来源和格式。
# 3. HTTP 请求构建和发送
OpenFeign 使用 HttpClient
、OkHttp
或 Ribbon
等 HTTP 客户端库来构建和发送 HTTP 请求。具体步骤如下:
- 解析注解:根据接口上的注解解析出请求方法、URL、请求参数等信息。
- 构建请求:使用解析出的信息构建 HTTP 请求。
- 发送请求:通过配置的 HTTP 客户端发送请求。
# 4. 响应处理
OpenFeign 处理 HTTP 响应并将结果转换为接口方法的返回类型。具体步骤如下:
- 接收响应:从 HTTP 客户端接收响应。
- 解析响应:将响应体解析为指定的返回类型。
- 返回结果:将解析后的结果返回给调用者。
# 总结
其他服务调用这些接口,先去OpenFeign中找,OpenFeign通过代理进行请求,得到结果后,返回给调用者。是不是有拦截器那味了。