SpringCloud——微服务实战:OpenFeign与Nacos服务调用详解

发布时间:2026/7/22 8:44:25
SpringCloud——微服务实战:OpenFeign与Nacos服务调用详解 这篇文章摘要主要讲述了在微服务架构中如何通过服务调用解决blog-info-service迁移时遇到的数据依赖问题。作者首先分析了直接访问数据库的错误方案会导致服务耦合随后提出了正确的解决方案使用OpenFeign进行服务间通信并引入api模块定义服务契约。文章详细阐述了完整的调用链流程包括Nacos服务发现和Feign远程调用的配合使用强调了微服务自治的重要性。最后总结了四个关键面试问题并指出这一节将SpringCloud的各个组件Gateway、Nacos、Feign等串联起来形成完整的知识链。目录4.3.3 blog-info-service 迁移 —— 第一次真正体现微服务调用一、原来的博客模块二、但是马上出现问题三、错误方案直接访问数据库服务耦合。四、正确方案服务调用五、这里引入 api 模块user-info-api六、user-info-service实现七、blog-service如何调用八、完整调用链九、这里重新理解 Nacos服务地址变化问题。十、这一节面试重点1. 为什么微服务之间不能直接调用Service2. 为什么需要api模块3. Feign为什么需要服务名4. Nacos和Feign关系十一、你现在整个 Spring Cloud 知识链已经串起来了4.3.4 Gateway 服务迁移继续我们进入4.3.3 blog-info-service 迁移 —— 第一次真正体现微服务调用这一节比用户服务迁移更重要。原因用户服务迁移只是拆模块。但是博客服务迁移会遇到真正的微服务问题一个服务需要另一个服务的数据怎么办这就是服务间通信OpenFeignAPI模块Nacos服务发现真正落地。一、原来的博客模块单体项目blog-system controller BlogController service BlogService mapper BlogMapper entity Blog调用浏览器 ↓ BlogController ↓ BlogService ↓ BlogMapper ↓ MySQL例如查询博客列表GetMapping(/list) public ListBlog list(){ return blogService.list(); }但是现在拆成微服务spring-cloud-blog ├── user-info-service │ └── blog-info-service博客代码全部迁移blog-info-service ├── controller │ BlogController ├── service │ BlogService ├── mapper │ BlogMapper ├── entity │ Blog └── BlogInfoApplication二、但是马上出现问题假设博客列表以前返回{ id:1, title:Spring Cloud学习, userId:1001 }现在前端希望{ id:1, title:Spring Cloud学习, user:{ id:1001, username:xiaolu } }怎么办以前同一个项目直接查userMapper.selectById(userId)即可。现在两个服务blog-service ❌ userMapper不存在。因为user-service另外一个 JVM。三、错误方案直接访问数据库有人会想到博客服务直接连接user_db查询用户。例如select * from user where id1001;看似简单。但是问题服务耦合。结构blog-service | | ↓ user_db那么用户服务存在意义降低。如果用户表改字段例如username 改成 nickname博客服务也要改。这违反微服务自治。四、正确方案服务调用架构blog-service | | ↓ user-service通过HTTP/RPC。流程用户请求博客列表 ↓ gateway ↓ blog-service ↓ 调用 user-service ↓ 返回用户信息 ↓ 组装博客数据 ↓ 返回前端五、这里引入 api 模块问题blog-service 怎么知道user-service 有什么接口比如查询用户User getUserById(Long id);如果直接写RestController不行。因为Controller是服务实现。所以抽接口。创建user-info-api结构user-info ├── user-info-api │ └── user-info-serviceuser-info-api只放接口。例如public interface UserApi { UserDTO getById(Long id); }注意没有Service没有数据库。只是契约。六、user-info-service实现真正代码RestController public class UserController implements UserApi { Override public UserDTO getById(Long id){ return userService.getById(id); } }关系接口 UserApi ↑ | | UserController ↑ | UserService七、blog-service如何调用blog-service引入dependency artifactId user-info-api /artifactId /dependency然后创建Feign接口FeignClient( nameuser-service ) public interface UserFeignClient extends UserApi { }这一步非常关键。你之前学OpenFeign。现在终于知道为什么需要它。八、完整调用链请求GET /blog/list进入Gatewaylocalhost:9000↓路由lb://blog-service↓blog-serviceBlogController↓查询博客BlogService↓发现需要用户调用UserFeignClient↓OpenFeign根据nameuser-service去Nacos找。↓Nacos返回user-service 192.168.1.10:8081↓HTTP调用↓UserController↓返回。整体Nacos ↑ | Gateway | | blog-service | Feign | user-service九、这里重新理解 Nacos以前你学Nacos注册发现。感觉只是服务列表。现在结合业务它解决服务地址变化问题。例如用户服务今天192.168.1.10:8081明天扩容192.168.1.11:8081 192.168.1.12:8081博客服务不用改代码。因为调用FeignClient(user-service)不是http://192.168.1.10:8081十、这一节面试重点1. 为什么微服务之间不能直接调用Service答因为服务运行在不同JVM中无法共享对象需要通过RPC或者HTTP通信。2. 为什么需要api模块答api模块定义服务契约实现接口和调用方解耦Feign可以基于接口生成远程调用代理。3. Feign为什么需要服务名答服务名用于Nacos服务发现通过服务名获取真实实例地址。4. Nacos和Feign关系一句话Nacos负责找服务Feign负责调用服务。十一、你现在整个 Spring Cloud 知识链已经串起来了之前你学的是零件Gateway JWT Nacos Feign LoadBalancer现在案例把零件组装客户端 ↓ Gateway (统一入口 JWT) ↓ Nacos (服务发现) ↓ Feign (远程调用) ↓ user-service/blog-service ↓ 数据库下一节进入4.3.4 Gateway 服务迁移这里会把你之前写的AuthGlobalFilter真正放入案例。重点网关如何统一鉴权为什么服务内部还需要校验JWT用户信息如何向下传递Header透传设计这一部分和你之前练的 Gateway Filter 完全对应。