远程调用OpenFeign应该如何设置

这是一个拓展性的问题:微服务架构项目中的远程调用 FeignClient 该写在哪里?远程调用 Feign 包该建在哪个模块里?

当然,这里只是笔者根据过往的开发经验来总结的,并不是标准答案,只是作为一个引申的知识点介绍给各位读者。

比如,订单微服务需要调用用户微服务下的 /getUserDetail/{userId} 接口来获取用户信息。这个接口的功能逻辑已经在用户微服务中实现且功能正常,如果想要通过 OpenFeign 远程调用,就需要实现一个 FeignClient 类,在订单微服务里引入 FeignClient 类并开启 OpenFeign 调用就完成了。这个 FeignClient 类可以在订单微服务工程中编写,也可以在用户微服务工程中编写,甚至有些团队会单独创建一个 Feign 模块用于存放所有的 FeignClient 类。毕竟,只要引入 OpenFeign 的依赖 JAR 包就可以编写 FeignClient 类,不需要与业务代码耦合。那么,也就引出了一个问题:FeignClient 是写在调用端(如案例中的订单微服务)、被调用端(如案例中的用户微服务),还是写在单独创建的 Feign 模块里呢?

newbee-mall-cloud 项目中的目录设计是写在被调用端的,各个微服务下都单独创建了对应的 xxx-api 模块用于存放 FeignClient 类,如果有其他微服务需要远程调用,直接引入对应的 xxx-api 依赖,之后就能够发起远程调用了。如此设计的原因如下。

在正常的企业开发模式下,微服务的细节是不对外公开的,如果A业务组想要B业务组提供一个远程调用接口,那么直接让B业务组编码即可,因为A业务组的开发人员不熟悉B业务组的代码,在这种情况下让B业务组来提供更合理。不仅如此,这种方式更加灵活和安全,B业务组想要暴露哪些业务接口,自行实现并暴露即可,不想暴露的就不用写在 Feign 包里了。比如,用户微服务下有 100 个接口,需要暴露的接口有 3 个,开发团队只需要在 FeignClient 类中暴露这 3 个接口即可。

如果写在 A 业务组的微服务里,那么A业务组的开发人员可能还需要查看由 B 业务组负责的微服务里有哪些接口,之后再去写 FeignClient 类,这种做法是不合理的,增加了上游微服务开发团队的工作量,并且如果每个开发团队都自行实现 FeignClient 类,代码就重复了。所以,由被调用方来做这个工作更好一点。

当然,所有的 FeignClient 类都被统一放在一个单独的模块下,也是一种实现方式。比如,在 newbee-mall-cloud 项目中,可以新建一个 newbee-mall-cloud-feign 模块,当前的所有 xxx-api 模块下的 FeignClient 类都可以统一放在 newbee-mall-cloud-feign 模块中,在需要远程调用时直接引入 newbee-mall-cloud-feign 模块即可。

项目骨架搭建完成后又引入了公用模块,并介绍了项目的目录规范,之后引入服务通信 OpenFeign 进行简单的编码,后续实战章节中的目录结构基本都是按照这个规范来做的,希望读者能够根据笔者提供的开发步骤顺利地完成本章的项目改造。