当前位置: 首页 > news >正文

已经用微服务了还用引入模块化开发?

POM模块化引入和RPC调用解决的是两个完全不同维度的问题。它们不是“二选一”的替代关系,而是“分层协作”的互补关系。

你之所以会有这个疑问,可能是因为把“代码的组织方式(模块化)”和“进程间的通信方式(RPC)”搞混了。让我们把这个问题拆开来看:

1. POM模块化:解决的是“代码复用”和“编译期依赖”

在微服务架构中,即使每个服务都是独立部署的进程,它们之间依然存在大量需要共享的代码。如果不使用POM模块化(即Maven多模块),你通常会面临以下问题:

  • 接口定义(契约)重复:服务A要调用服务B,服务B的接口签名(DTO类、枚举)如果只在B项目里写一遍,服务A就需要硬编码字符串去调用,或者复制粘贴一份代码。这会导致每维护一份副本,就多一分腐化的风险

  • 实体类与工具类:通用的异常类、BaseEntity、工具类(如StringUtilsRedisUtil)、常量池。如果没有模块化,每个服务都要自己写一份,或者通过拷贝代码来共享,维护成本极高。

POM模块化的做法通常是:
将项目拆分为:

  • xxx-api模块:存放接口声明(Java Interface)、DTO(数据传输对象)、枚举Feign Client接口(如果你用Spring Cloud)。

  • xxx-service模块:存放业务逻辑、数据库操作等。

  • xxx-common模块:存放公共工具类。

作用:服务A通过POM引入服务B的api模块,仅仅是为了引入那些定义好的DTO类和Feign接口,而不是为了引入服务B的业务逻辑实现。

2. RPC调用:解决的是“运行时”的“网络通信”

RPC(如Dubbo、gRPC,或者Spring Cloud中的Feign/OpenFeign)解决的是进程间通信(IPC)的问题。

微服务虽然拆开了,但它们需要互相说话。RPC框架的作用是屏蔽网络编程的复杂性,让你感觉像是在调用本地方法一样,去调用另一个服务器上的方法。

3. 为什么两者必须结合使用?

如果你“不用POM模块化引入”,而想直接使用RPC调用,你会遇到以下几种极其痛苦的场景:

场景一:接口定义漂移

服务A要调用服务B。
如果不引入服务B的api模块,开发者通常会在服务A里硬编码服务B的接口路径和参数类型。

  • 例如:String url = "" + userId;

  • 后果:当服务B的接口路径从/user/detail改成/user/info,或者参数名改了,服务A编译期不会报错,只有在运行时才会报错(404或反序列化失败)。在微服务规模扩大后,这种“硬编码”和“拷贝DTO”会让架构变得极其脆弱。

场景二:重复定义与不一致

如果每个调用方都自己定义一份被调用方的DTO:

  • 服务B修改了UserDTO,增加了字段age,删除了字段name

  • 服务A自己拷贝的那份旧UserDTO没有变。

  • 调用时,RPC框架进行反序列化,会出现字段丢失、类型转换错误,甚至因为Serizlization ID不匹配直接报错。

场景三:Feign/Dubbo Interface 无法共享

在Spring Cloud Alibaba或原生Spring Cloud生态中,Feign Client 或 Dubbo 的接口定义通常就是一个普通的Java接口。

  • 正确的做法:把这个接口写在xxx-api模块里。服务B实现它,服务A引入它并调用。

  • 没有模块化的做法:服务A如果要调用服务B,需要重新写一遍Feign Client的定义,或者通过配置类动态拼URL。这样一旦接口签名变化,所有调用方都得手动修改,容易遗漏。

4. 你的困惑可能来自于“过度依赖”

你可能看到有些项目里,一个服务引入了另一个服务的api模块,导致引入了很多不必要的传递依赖,甚至造成了耦合过重——修改一个接口,所有依赖方都需要重新打包部署。

但这不是模块化本身的错,而是模块拆分粒度的问题。

正确的微服务模块化实践应该是:

  1. 轻量级API包xxx-api模块应该只包含接口定义和DTO,绝对不能包含业务逻辑、数据库驱动、具体的实现类。

  2. 版本管理:API模块应该独立版本号。当接口变更不兼容时,升级大版本;兼容性修改时,升级小版本。调用方可以选择是否升级版本。

  3. 解耦:服务A引入服务B的api模块,仅代表“我知道怎么和你说话”,不代表“我必须和你绑定在一起”。

总结

不用POM模块化引入,只用RPC调用,本质上是在进行原始的手工HTTP调用(拼接URL、手动封装JSON、手动处理异常)。

  • POM模块化解决的是编译期的类型安全契约统一代码复用。它确保在写代码时,如果接口参数写错了,IDE会直接报红线。

  • RPC解决的是运行期的网络传输负载均衡服务发现

在成熟的微服务项目中,两者是黄金搭档用POM模块化(api包)来定义契约,用RPC框架来实现契约的远程执行。缺少了模块化引入,你的微服务就会退回到“通过文档手动同步接口”的原始状态,那正是微服务诞生之前,SOA架构乃至更早时期开发人员所面临的痛点。

http://www.jsqmd.com/news/535557/

相关文章:

  • 2026 SAE法兰十大品牌推荐:SAE焊接法兰SAE扩口式法兰生产SAE扩口/保持环法兰的厂家无焊接SAE法兰有船级社形式认可证书的SAE法兰厂家权威榜单 - 呼呼拉呼
  • 旧设备焕新:用OpenCore Legacy Patcher开源工具重获新生
  • 在LubanCat RK3568上跑通YOLOv5:手把手教你用RKNN-Toolkit-lite2部署目标检测模型
  • nli-distilroberta-base在智能写作中的实战:大纲与正文段落逻辑连贯性自动评估
  • 国标视频平台API治理:从混乱到有序的自动化方案
  • MelonLoader:Unity游戏模组加载框架全解析
  • 新手入门网络安全:从 0 基础到实战上岗,保姆级避坑 + 工具全汇总
  • PyTorch 2.8镜像部署案例:政务AI问答系统私有化部署的硬件适配方案
  • jfinal_cms-v5.1.0 代码审计
  • [Redis小技巧27]Redis Cluster 全景指南:Gossip 协议、故障转移与生产避坑实战
  • 创新部署策略:如何高效配置OpenCore黑苹果安装环境
  • 2026 年工业防腐涂料专业品牌选择 行业经验参考
  • OrCAD Library Builder 17.2安装避坑指南:从破解失败到成功导出的完整流程
  • Jimeng AI Studio效果展示:Z-Image Turbo在人物肖像生成中的皮肤质感表现
  • BlendLuxCore:重新定义3D渲染的光影魔术师
  • 洛谷 P1192:台阶问题 ← 动态规划 + 前缀和优化
  • 告别官方工具:手把手教你用Python+OpenNI2驱动Astra Pro,打造自定义深度应用
  • Ubuntu 20.04 下 Vitis 2021.2 离线安装全记录:从77G压缩包到环境变量配置(附磁盘分区建议)
  • 轻量级JS工具库Verge:提升前端开发效率的实战指南
  • 3个认知转变:从文档奴隶到可视化架构师
  • JavaScript——JSON序列化和反序列化
  • mFS:面向EEPROM的轻量级嵌入式文件系统
  • 必收藏!京东大模型算法工程师面经+薪资全解析 985硕纠结要不要去?
  • 如何在ESXi 6.7上完美驱动Realtek RTL8125网卡:完整编译与部署指南
  • 有关zstuacm集训队的部分内容提醒
  • 10分钟掌握Keycloak与Spring Boot集成:告别重复造轮子的终极指南
  • 《信息系统项目管理师教程(第4版)》——成本管理避坑考点
  • 如何解决多显示器DPI缩放混乱?SetDPI工具实战指南
  • LFM2.5-1.2B-Thinking-GGUF效果展示:32K上下文下长篇小说人物关系图谱生成示意
  • 我用 Claude Skills 做了个「文章自动配图」技能