Spring Cloud OpenFeign + Nacos 实战教程:像调用本地方法一样调用远程微服务

💡 一、为什么要用 Feign?

在微服务架构中,服务之间往往需要频繁通信。

如果你还在使用 RestTemplate

java 复制代码
RestTemplate restTemplate = new RestTemplate();
UserDTO user = restTemplate.getForObject("http://user-service/users/1", UserDTO.class);

那么每个请求都要手动拼 URL、处理参数、异常和日志,非常繁琐。

Feign 让我们能像调用本地方法一样发起远程请求👇:

java 复制代码
UserDTO user = userClient.getUserById(1L);

它的原理是:

通过接口 + 注解 自动生成 HTTP 客户端代码。


🧩 二、核心依赖与环境

我们将用两个微服务演示 Feign 的调用过程:

服务名称 说明 端口
user-service 提供用户信息接口 8081
order-service 通过 Feign 调用 user-service 8082

Nacos 用于服务注册发现。

1. 统一父依赖

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

🧱 三、项目结构

plaintext 复制代码
feign-demo/
├── user-service/
│   ├── UserApplication.java
│   ├── controller/UserController.java
│   └── model/UserDTO.java
│
└── order-service/
    ├── OrderApplication.java
    ├── controller/OrderController.java
    ├── client/UserClient.java
    ├── client/UserClientFallback.java
    └── model/UserDTO.java

⚙️ 四、Nacos 配置

确保 Nacos 已启动(默认地址 localhost:8848):

bash 复制代码
sh nacos/bin/startup.sh -m standalone

✅ user-service 的 application.yml

yaml 复制代码
server:
  port: 8081
spring:
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

✅ order-service 的 application.yml

yaml 复制代码
server:
  port: 8082
spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: full
  circuitbreaker:
    enabled: true

logging:
  level:
    com.example.order.client: DEBUG

👤 五、user-service 实现

UserApplication.java

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

UserController.java

java 复制代码
@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public UserDTO getUserById(@PathVariable Long id) {
        return new UserDTO(id, "张三-" + id);
    }
}

UserDTO.java

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {
    private Long id;
    private String name;
}

📦 六、order-service 实现

OrderApplication.java

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

UserClient.java

java 复制代码
@FeignClient(name = "user-service", fallback = UserClientFallback.class)
public interface UserClient {

    @GetMapping("/users/{id}")
    UserDTO getUserById(@PathVariable("id") Long id);
}

UserClientFallback.java

java 复制代码
@Component
public class UserClientFallback implements UserClient {

    @Override
    public UserDTO getUserById(Long id) {
        return new UserDTO(id, "(熔断:无法获取用户信息)");
    }
}

OrderController.java

java 复制代码
@RestController
@RequiredArgsConstructor
@RequestMapping("/orders")
public class OrderController {

    private final UserClient userClient;

    @GetMapping("/{userId}")
    public String createOrder(@PathVariable Long userId) {
        UserDTO user = userClient.getUserById(userId);
        return "订单已创建,用户:" + user.getName();
    }
}

🧠 七、运行与验证

1️⃣ 启动 Nacos

bash 复制代码
sh nacos/bin/startup.sh -m standalone

2️⃣ 启动 user-service(端口 8081)

3️⃣ 启动 order-service(端口 8082)

4️⃣ 访问接口测试

复制代码
GET http://localhost:8082/orders/1

返回结果:

text 复制代码
订单已创建,用户:张三-1

5️⃣ 熔断验证

关闭 user-service 再访问:

text 复制代码
订单已创建,用户:(熔断:无法获取用户信息)

✅ 熔断逻辑生效!


🧩 八、Feign 的常见配置与技巧

功能 说明 示例
设置超时 防止接口卡死 feign.client.config.default.connectTimeout
打印日志 调试接口调用 Logger.Level.FULL
指定路径前缀 服务路径统一 @FeignClient(path = "/api/v1")
参数映射 支持 Path / Query / Body @PathVariable @RequestParam @RequestBody
负载均衡 多实例自动轮询 集成 Nacos 或 Eureka 自动实现

🪄 九、Feign vs RestTemplate 对比

对比项 RestTemplate Feign
调用方式 手动拼 URL 接口声明式
可维护性
负载均衡 需手动配置 内置支持
熔断支持 需额外封装 一行配置启用
代码简洁度 👎 👍👍👍

🧰 十、可视化调用流程图

OrderService FeignClient Nacos UserService 调用 getUserById(1) 查询 user-service 实例地址 返回实例信息 GET /users/1 返回 UserDTO 注入返回对象 OrderService FeignClient Nacos UserService


一句话总结

Feign 让微服务之间的调用"像写接口一样简单",

是 Spring Cloud 架构中不可或缺的通信利器。


实用小工具

App Store 截图生成器应用图标生成器在线图片压缩utc timestamp, ctf toolChrome插件-强制开启复制-护眼模式-网页乱码设置编码
乖猫记账,AI智能分类的最佳聊天记账App。
Elasticsearch可视化客户端工具

相关推荐
重生之我要当java大帝3 小时前
java微服务-尚医通-编写医院设置接口上
java·数据库·微服务
Mu.3873 小时前
初始Spring
java·数据库·spring
xiaogg36784 小时前
阿里云k8s部署微服务yaml和Dockerfile文件脚本
阿里云·微服务·kubernetes
超龄超能程序猿5 小时前
Spring AI Alibaba 与 Ollama对话历史的持久化
java·人工智能·spring
hrrrrb5 小时前
【Spring Security】认证(二)
java·后端·spring
cxyxiaokui0016 小时前
🔥不止于三级缓存:Spring循环依赖的全面解决方案
java·后端·spring
MrSYJ8 小时前
学完涨工资的技巧2:Spring Authorization Server如何签发JWTToken
java·spring boot·微服务
珹洺8 小时前
Java-Spring入门指南(二十六)Android Studio下载与安装
java·spring·android studio