spring-cloud-starter-openfeign现实中的运行逻辑
spring-cloud-starter-openfeign 是 Spring Cloud 生态中声明式的 HTTP 客户端,核心作用是让你像调用本地方法一样调用远程 HTTP 接口,不用手写复杂的 RestTemplate/OkHttp 代码,大幅简化微服务间的通信。
· 声明式:你只需要定义一个接口,加几个注解,Spring 会自动帮你实现接口的 HTTP 调用逻辑,不用写一行请求代码。
· 底层依赖:基于 Netflix Feign 封装,默认用 Spring MVC 注解(@GetMapping/@PostMapping 等),也兼容 Feign 原生注解。
· 核心优势:集成负载均衡(默认 Ribbon)、熔断器(Hystrix/Sentinel)、请求 / 响应拦截、参数解析等,开箱即用。
安装依赖
java
<!-- Spring Cloud OpenFeign 核心依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId>
<!-- 版本建议和 Spring Cloud 版本匹配,比如 2023.0.0 -->
<version>2023.0.0</version>
</dependency>
<!-- 若需要负载均衡(微服务必加) -->
<dependency>
<groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
定义 Feign 客户端接口
假设你要调用远程服务 SC-USER的 /user/{id} 接口:
java
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// name:远程服务名(注册中心中的服务名),url:本地测试可直接指定地址(非微服务场景)
@FeignClient(name = " sc-user")
public interface UserFeignClient {
// 完全复用 Spring MVC 注解,和本地 Controller 写法一致
@GetMapping("/user/{id}")
UserDTO getUserById(@PathVariable("id") Long id);
// 复杂请求示例:POST + 请求体
@PostMapping("/user")
UserDTO createUser(@RequestBody UserDTO userDTO);
}
// 配套的实体类(和远程服务返回结构一致)
class UserDTO {
private Long id;
private String name;
private Integer age;
}
配置路由网关
java
spring:
application:
name: sc-gateway
cloud:
nacos:
discovery:
server-addr: 192.168.0.54:****
metadata:
region: default
# 路由网关配置
gateway:
# 设置与服务注册发现组件结合,这样可以采用服务名的路由策略
discovery:
locator:
enabled: true
# 配置路由规则
routes:
# 采用自定义路由 ID(有固定用法,不同的 id 有不同的功能,详见:https://cloud.spring.io/spring-cloud-gateway/2.0.x/single/spring-cloud-gateway.html#gateway-route-filters)
- id: SC-USER
# 采用 LoadBalanceClient 方式请求,以 lb:// 开头,后面的是注册在 Nacos 上的服务名
uri: lb://sc-user
# Predicate 翻译过来是"谓词"的意思,必须,主要作用是匹配用户的请求,有很多种用法
predicates:
# Method 方法谓词,这里是匹配 GET 和 POST 等请求
- Path=/user/**
filters:
- StripPrefix=1
profiles:
active: local
main:
allow-bean-definition-overriding: true
banner-mode: "off"
#开启sentinel适配feign
feign:
sentinel:
enabled: true
ribbon:
ReadTimeout: 60000
ConnectTimeout: 60000
management:
endpoints:
web:
exposure:
#include: ["beans","metrics","info","health","loggers"]
include: "*"
security:
enabled: false
添加负载均衡
依赖支持
java
<!-- OpenFeign 核心依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2023.0.0</version> </dependency>
<!-- 负载均衡核心依赖(必须加,否则无法根据服务名寻址) -->
<dependency>
<groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- 注册中心依赖(以 Nacos 为例,根据你的注册中心替换) -->
<dependency>
<groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2023.0.1.0</version>
</dependency>
开启服务发现和 Feign
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
// 开启服务发现(从注册中心获取实例)
@EnableDiscoveryClient
// 开启 Feign 客户端扫描
@EnableFeignClients
@SpringBootApplication
public class FeignConsumerApplication {
public static void main(String[] args)
{
SpringApplication.run(FeignConsumerApplication.class, args);
}
}
调用 Feign 接口(负载均衡自动生效)
java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class UserController
{
@Resource
private UserFeignClient userFeignClient;
@GetMapping("/user/{id}")
public String getUser(@PathVariable Long id) {
// 多次调用会自动分发到不同实例(默认轮询)
return userFeignClient.getUserById(id);
}
}
完毕
· OpenFeign 实现负载均衡的核心是「服务名调用 + LoadBalancer 依赖 + 服务发现」,无需手写负载逻辑;
· 关键步骤:引 LoadBalancer 依赖 → 开启服务发现 → FeignClient 只写服务名 → 自动轮询分发请求;
· 可通过配置自定义负载策略(随机 / 权重等),满足不同业务需求。