OpenFeign 是 Spring Cloud 里用来做服务调用的工具。
OpenFeign可以让你像调用本地 Java 方法一样,去调用另一个微服务的接口。
在一个简单的下单储存的项目里,就是:
order 服务调用 stock 服务
以前可能用 RestTemplate,现在更常用 OpenFeign。
1. 没有 OpenFeign 时怎么调用?
比如 order 服务要调用 stock 服务扣库存。
用 RestTemplate 可能这样写:
String result = restTemplate.getForObject(
"http://stock-service/stock/reduct",
String.class
);
这段代码的意思是:
order 服务主动发送 HTTP 请求,调用 stock 服务的 /stock/reduct 接口
但是这种写法有点像 Python 里的:
requests.get("http://stock-service/stock/reduct")
能用,但写多了会乱。
2. OpenFeign 是怎么做的?
OpenFeign 的思想是:
你只需要写一个 Java 接口,告诉它要调用哪个服务、哪个接口,剩下的 HTTP 请求由 OpenFeign 自动完成。
比如:
@FeignClient("stock-service")
public interface StockFeignService {
@GetMapping("/stock/reduct")
String reduct();
}
这段代码看起来只是一个接口,但它的意思是:
我要调用名叫 stock-service 的服务
调用它的 /stock/reduct 接口
返回 String 结果
然后在 order 服务里直接调用:
stockFeignService.reduct();
这就像调用本地方法一样。
3. OpenFeign 在 order + stock 项目里的位置
你的项目大概是:
xs-springcloudalibaba
├── order
└── stock
业务流程是:
浏览器 / Postman
↓
order 服务:/order/add
↓
OpenFeign 调用
↓
stock 服务:/stock/reduct
也就是说:
OpenFeign 负责 order 服务调用 stock 服务
4. RestTemplate 和 OpenFeign 的区别
| 方式 | 写法 | 特点 |
|---|---|---|
RestTemplate |
手动拼 URL | 比较原始 |
OpenFeign |
写接口调用 | 更优雅,更适合微服务 |
RestTemplate 写法
restTemplate.getForObject(
"http://stock-service/stock/reduct",
String.class
);
OpenFeign 写法
stockFeignService.reduct();
明显后者更像正常 Java 方法调用。
5. OpenFeign 怎么用?
第一步:在 order 服务的 pom.xml 加依赖
因为是 order 调用别人,所以依赖加在 order 服务里。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
如果你还用 Nacos 服务发现,也要有 Nacos 依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
第二步:在启动类上开启 Feign
OrderApplication.java:
@SpringBootApplication
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
重点是这个注解:
@EnableFeignClients
意思是:
开启 OpenFeign 功能。
第三步:写 Feign 接口
在 IDEA 里的目录结构大概是:
order
└── src
└── main
└── java
└── com.tulingxueyuan.order
├── controller
│ └── OrderController.java
├── feign
│ └── StockFeignService.java
└── OrderApplication.java
在 order 服务下面建一个包:
com.tulingxueyuan.order.feign
然后写:
package com.tulingxueyuan.order.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient("stock-service")
public interface StockFeignService {
@GetMapping("/stock/reduct")
String reduct();
}
解释一下:
@FeignClient("stock-service")
表示:
我要调用 Nacos 里名字叫 stock-service 的服务
@GetMapping("/stock/reduct")
表示:
我要调用 stock-service 服务里的 /stock/reduct 接口
6. Controller 里怎么用?
OrderController.java:
package com.tulingxueyuan.order.controller;
import com.tulingxueyuan.order.feign.StockFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private StockFeignService stockFeignService;
@GetMapping("/add")
public String add() {
System.out.println("创建订单成功");
String result = stockFeignService.reduct();
return "下单成功," + result;
}
}
当你访问:
http://localhost:8081/order/add
执行过程是:
进入 OrderController 的 add()
↓
打印:创建订单成功
↓
调用 stockFeignService.reduct()
↓
OpenFeign 自动请求 stock 服务的 /stock/reduct
↓
stock 服务返回结果
↓
order 服务把结果返回给浏览器
7. stock 服务要有什么接口?
StockController.java:
package com.tulingxueyuan.stock.controller;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/stock")
public class StockController {
@GetMapping("/reduct")
public String reduct() {
System.out.println("扣减库存成功");
return "库存扣减成功";
}
}
8. Nacos 和 OpenFeign 的关系
OpenFeign 本身负责:
发起服务调用
Nacos 负责:
告诉 OpenFeign:stock-service 到底在哪台机器、哪个端口
比如 stock-service 注册到 Nacos:
stock-service -> 127.0.0.1:8082
那么 OpenFeign 调用:
@FeignClient("stock-service")
它会去 Nacos 找 stock-service 的真实地址。
所以它们的关系是:
Nacos:负责找服务
OpenFeign:负责调用服务
9. 可以这样记
在 Spring Cloud Alibaba 里:
Nacos:服务注册与发现
OpenFeign:服务之间互相调用
Seata:保证多个服务的数据一致
Sentinel:限流、熔断、降级
针对你的项目:
order 调用 stock:用 OpenFeign
order 找到 stock:靠 Nacos
order 和 stock 事务一致:靠 Seata
10. 总结
OpenFeign 就是微服务之间的 HTTP 调用工具。
它把这种写法:
restTemplate.getForObject("http://stock-service/stock/reduct", String.class);
变成这种写法:
stockFeignService.reduct();
所以可以先记住:
OpenFeign 的作用是:让一个服务调用另一个服务时,写起来像调用本地方法一样。