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可视化客户端工具

相关推荐
一定要AK7 小时前
Spring 入门核心笔记
java·笔记·spring
凯尔萨厮7 小时前
创建SpringWeb项目(Spring2.0)
spring·mvc·mybatis
木子欢儿9 小时前
Docker Hub 镜像发布指南
java·spring cloud·docker·容器·eureka
Devin~Y9 小时前
高并发电商与AI智能客服场景下的Java面试实战:从Spring Boot到RAG与向量数据库落地
java·spring boot·redis·elasticsearch·spring cloud·kafka·rag
鬼先生_sir10 小时前
Spring Cloud 微服务监控实战:SkyWalking + Prometheus+Grafana 全栈解决方案
运维·spring cloud·grafana·prometheus·skywalking
凯尔萨厮13 小时前
Spring学习笔记(基于配置文件)
spring
bobasyu13 小时前
Claude Code 源码笔记 -- queryLoop
java·笔记·spring
计算机学姐13 小时前
基于SpringBoot的高校竞赛管理系统
java·spring boot·后端·spring·信息可视化·tomcat·mybatis
文慧的科技江湖13 小时前
光储充协同的终极闭环:用SpringCloud微服务打造“发-储-充-用“智能能源网络 - 慧知开源充电桩管理平台
java·开发语言·spring cloud·微服务·能源·充电桩开源平台·慧知重卡开源充电桩平台
砍材农夫13 小时前
spring-ai 第七模型介绍-向量模型
java·人工智能·spring