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

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

💡 一、为什么要用 Feign?

在微服务架构中,服务之间往往需要频繁通信。
如果你还在使用 RestTemplate

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

那么每个请求都要手动拼 URL、处理参数、异常和日志,非常繁琐。
Feign 让我们能像调用本地方法一样发起远程请求👇:

UserDTO user = userClient.getUserById(1L);

它的原理是:

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


🧩 二、核心依赖与环境

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

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

Nacos 用于服务注册发现。

1. 统一父依赖

<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>***.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>

🧱 三、项目结构

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):

sh nacos/bin/startup.sh -m standalone

✅ user-service 的 application.yml

server:
  port: 8081
spring:
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

✅ order-service 的 application.yml

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:
    ***.example.order.client: DEBUG

👤 五、user-service 实现

UserApplication.java

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

UserController.java

@RestController
@RequestMapping("/users")
public class UserController {

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

UserDTO.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {
    private Long id;
    private String name;
}

📦 六、order-service 实现

OrderApplication.java

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

UserClient.java

@FeignClient(name = "user-service", fallback = UserClientFallback.class)
public interface UserClient {

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

UserClientFallback.java

@***ponent
public class UserClientFallback implements UserClient {

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

OrderController.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

sh nacos/bin/startup.sh -m standalone

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

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

4️⃣ 访问接口测试

GET http://localhost:8082/orders/1

返回结果:

订单已创建,用户:张三-1

5️⃣ 熔断验证

关闭 user-service 再访问:

订单已创建,用户:(熔断:无法获取用户信息)

✅ 熔断逻辑生效!


🧩 八、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 接口声明式
可维护性
负载均衡 需手动配置 内置支持
熔断支持 需额外封装 一行配置启用
代码简洁度 👎 👍👍👍

🧰 十、可视化调用流程图


一句话总结
Feign 让微服务之间的调用“像写接口一样简单”,
是 Spring Cloud 架构中不可或缺的通信利器。


实用小工具

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

转载请说明出处内容投诉
CSS教程网 » Spring Cloud OpenFeign + Nacos 实战教程:像调用本地方法一样调用远程微服务

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买