在springcloud中关于feign的疑问,如下这么写目的是什么?

1.项目中有两个模块,一个demo-api,一个demo-Service
2.在demo-api中有如下接口定义

@FeignClient(name = "demo-api", url = "${feign.client.config.demo-api.url}")
@RequestMapping("/api/demo")
public interface DemoClient {

    @PostMapping("/list")
    GlobalResponse<?> list(@RequestBody DemoVM vm);
   
}

3.在demo-Service中有接口的实现

@Slf4j
@RestController
public class DemoController implements DemoClient {

    @Override
    public GlobalResponse<?> list(@RequestBody DemoVM vm) {
      
        return GlobalResponse.success(refrigerantService.getList(vm));
    }
}

4.配置文件中

feign:
  client:
    config:
      default:
        connectTimeout: 3000
        readTimeout: 10000
        loggerLevel: full
      demo-api:
        url: http://demo:8080    
      gateway-demo-client:
        url: http://spring-boot-inventory.qd-aliyun.demo.net
        Authorization: 5df3a980904ac5aa3e9a1ceab4dae9aa
          - com.demo.material.service.feign.interceptor.DemoFeignInterceptor

我的疑问
1.分成两个模块,在demo-api中定义接口,在demo-Service中实现接口,目的是什么,直接就一个模块不行吗,为啥要分开?
2.@FeignClient注解中,name全局搜索也没有搜到,name定义有啥用?url有啥用啊?
我看前端接口直接请求的路经就是/api/demo/list,请求已经到了本项目,再配置url感觉没有用啊?
3.gateway-demo-client有啥用,项目全局搜索也搜不到哪里用到了?
4.为啥项目都是-api,-service分成两个模块,我只写一个模块,把feign定义与实现写在一起可以吗

回复
阅读 558
3 个回答

写在前面:

你的疑问很正常,但是我建议你以后这种问题不需要提问,心里批评一下前开发人员就行了。

首先你提出这个问题的思路,是建立在你手上的项目做法正确,但是我(也就是你)不清楚为什么要这么做。

那么这种思路我认为应该调整一下,抱着批判的眼光去看待这些项目,实际上大多数的项目有着各种奇奇怪怪的毛病。

回答疑问

  1. 一般来说分成两个模块的目的是为了将两种业务逻辑分开开发,以保证代码逻辑的清晰性,和不同业务逻辑下所需机器配置不一样的情况下,能够灵活的扩展。
    但是你这个项目情况下看来,如果不是有请求量特别大想要提高吞吐量的需求,那么确实没有必要,就算分开为了提高吞吐量,也有 spring cloud gateway 这个更好的选择。
  2. name 可以不填,name 是用于 spring cloud 集群中,找到对应的负载机器使用的。在你这个项目的情况下,前端实际上是先请求到 api,api 再转发到 demo-Service。
  3. 如果配置了一个东西,看起来没啥用,找了半天也没用,那确实是没啥用,看名字就是一个用于测试的配置,结合配置看,像是一个发起请求之前做的权限认证。
  4. 与第一个问题重复,就是可以的,分开做在你这个项目情况下就是多此一举。

微服务之间通过Feign相互调用的场景,需要把API定义单独放到一个包内,甚至单独一个项目。

因为A服务如果想调用B服务,需要B服务提供API定义,不然A服务就要自己实现B服务的API定义。

同理,B服务想调用A服务,也需要A服务提供API定义。

推广到更多服务,服务之间相互调用会变得非常复杂,服务之间的API定义也会重复。

所以更好的做法,把API单独放到一个包内,想调用哪个服务的API,就直接引用即可。

随着微服务越来越多,API的定义也越来越多,项目也会逐渐膨胀,这时候把API单独作为一个项目,可以避免项目越来越复杂。

其次,DemoController没必要实现DemoClient接口,直接通过Autowire或者Resource注入DemoClient实例即可,Feign会自动生产DemoClient的实现类。

DemoController实现DemoClient接口增加完全没必要的耦合度

第一个问题:假设一个项目里有多个模块,每个模块是单独部署的微服务,例如有服务a、b、c,a通过feign调用c的接口,如果c分为api和service,那么只需要依赖c的api模块,同理b想要调用c的接口,也只需要依赖c的api模块即可

其他问题已有

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏