0


使用Feign进行微服务之间的接口调用:Spring Cloud Alibaba中的声明式服务调用

一、Feign介绍

  1. Feign是一个声明式的**HTTP客户端框架**,用于简化微服务架构中服务之间的通信。它是Spring Cloud框架的一部分,旨在提供一种优雅且易于使用的方式来定义和调用HTTP请求。
  2. Feign的设计目标是让服务之间的通信变得更加简单和直观。通常情况下,在微服务架构中,一个服务需要调用另一个服务的API来获取数据或执行操作。使用传统的方式,我们需要手动编写HTTP请求、处理请求和响应等操作,而Feign的出现简化了这个过程。
  3. 使用Feign,只需定义一个接口来描述要调用的服务的API,然后通过注解来配置请求和响应的处理方式。Feign会根据接口定义自动生成可用的HTTP请求,将请求发送到目标服务,并将响应转换为适当的对象类型返回。

Feign具有以下特性和优势:

  1. 声明式的API定义:通过简单地定义接口,可以清晰地描述服务之间的通信,而不必关注底层的HTTP细节。
  2. 内置负载均衡支持:Feign与Spring Cloud的服务注册和发现机制集成,可以自动实现负载均衡,轻松处理多个实例的服务调用。
  3. 请求和响应的自动序列化和反序列化:Feign可以自动处理请求和响应的序列化和反序列化,使您能够以面向对象的方式处理数据。
  4. 整合服务熔断和限流:Feign与Spring Cloud的熔断器(如Hystrix)和限流器(如Sentinel)集成,可以提供服务熔断和限流的能力,增加系统的稳定性和可靠性。
  5. 易于扩展:Feign提供了可插拔的机制,允许您通过自定义配置和拦截器等方式来扩展和定制其行为。

二、Feign的使用

这里我以 pig 项目为例进行说明。项目地址:https://gitee.com/log4j/pig

1. 项目模块说明

  1. pig
  2. ├── pig-auth -- 授权服务提供[3000]
  3. └── pig-common -- 系统公共模块
  4. ├── pig-common-bom -- 全局依赖管理控制
  5. ├── pig-common-core -- 公共工具类核心包
  6. ├── pig-common-datasource -- 动态数据源包
  7. ├── pig-common-job -- xxl-job 封装
  8. ├── pig-common-log -- 日志服务
  9. ├── pig-common-mybatis -- mybatis 扩展封装
  10. ├── pig-common-seata -- 分布式事务
  11. ├── pig-common-security -- 安全工具类
  12. ├── pig-common-swagger -- 接口文档
  13. ├── pig-common-feign -- feign 扩展封装
  14. └── pig-common-xss -- xss 安全封装
  15. ├── pig-register -- Nacos Server[8848]
  16. ├── pig-gateway -- Spring Cloud Gateway网关[9999]
  17. └── pig-upms -- 通用用户权限管理模块
  18. └── pig-upms-api -- 通用用户权限管理系统公共api模块
  19. └── pig-upms-biz -- 通用用户权限管理系统业务处理模块[4000]
  20. └── pig-visual
  21. └── pig-monitor -- 服务监控 [5001]
  22. ├── pig-codegen -- 图形化代码生成 [5002]
  23. ├── pig-sentinel-dashboard -- 流量高可用 [5003]
  24. └── pig-xxl-job-admin -- 分布式定时任务管理台 [5004]

2. Feign客户端定义

(1)引入Feign依赖

在pig-upms-api模块和pig-upms-biz模块都需要引入feign依赖:

  1. <!--feign 注解依赖-->
  2. <dependency>
  3. <groupId>com.pig4cloud</groupId>
  4. <artifactId>pig-common-feign</artifactId>
  5. <optional>true</optional>
  6. </dependency>

(2)定义位置

  1. 在代码中可以看到,Feign的客户端定义在了 pig-upms-api 模块中。将Feign的客户端定义在pig-upms-api模块下是一种常见的设计模式。这种模式的目的是将Feign的客户端接口定义为API模块的一部分,使得其他模块可以通过引入pig-upms-api依赖来使用该API,并通过Feign实现与pig-upms-biz模块(通用用户权限管理系统的业务处理模块)之间的通信。

(3)Feign客户端定义

以RemoteUserService为例:

  1. //标识这是一个Feign客户端接口,contextId指定客户端的id,用于和其他客户端区分
  2. //value="pig-upms-biz" 指定了要调用的服务名称
  3. @FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.UMPS_SERVICE)
  4. public interface RemoteUserService {
  5. //通过用户名查询用户、角色信息
  6. //@GetMapping注解指定了要调用的HTTP GET请求的路径。这里是 /user/info/{username}
  7. //headers指定了请求的头部信息,这里HEADER_FROM_IN的值是"from=Y"
  8. @GetMapping(value = "/user/info/{username}", headers = SecurityConstants.HEADER_FROM_IN)
  9. R<UserInfo> info(@PathVariable("username") String username);
  10. //通过手机号码查询用户、角色信息
  11. @GetMapping(value = "/app/info/{phone}", headers = SecurityConstants.HEADER_FROM_IN)
  12. R<UserInfo> infoByMobile(@PathVariable("phone") String phone);
  13. //根据部门id,查询对应的用户 id 集合
  14. @GetMapping(value = "/user/ids", headers = SecurityConstants.HEADER_FROM_IN)
  15. R<List<Long>> listUserIdByDeptIds(@RequestParam("deptIds") Set<Long> deptIds);
  16. }

实际上这个Feign客户端会发送请求到SysUserController:

(4)在其他模块测试

比如说,我想要在 pig-codegen 模块下使用 Feign 进行接口调用,需要先在 codegen 模块引入 pig-upms-api 的依赖,因为我们将Feign的客户端定义在了pig-upms-api下。

  1. <!--upms api、model 模块-->
  2. <dependency>
  3. <groupId>com.pig4cloud</groupId>
  4. <artifactId>pig-upms-api</artifactId>
  5. </dependency>

编写一个测试Controller:

  1. @RestController
  2. @RequiredArgsConstructor //自动生成构造方法,在生成FeignDemoController会将remoteUserService传入
  3. @RequestMapping("/feignDemo")
  4. public class FeignDemoController {
  5. //注入Feign客户端接口 RemoteUserService
  6. //定义为final 确保在实例化后变量不会发生意外改变
  7. private final RemoteUserService remoteUserService;
  8. @Inner(value = false)
  9. @GetMapping("/test")
  10. public R<UserInfo> test() {
  11. //假设传入的用户名是 admin
  12. String username = "admin";
  13. //调用feign中的info方法
  14. return remoteUserService.info(username);
  15. }
  16. }

启动服务测试,可以看到成功获取到了admin用户的信息:

补充:关于在两种注入方式的理解:

在注入

  1. remoteUserService

属性时,可以使用

  1. @RequiredArgsConstructor

注解或

  1. @Autowired

注解两种方式。这两种方式有以下区别:

  1. @RequiredArgsConstructor: 当在类上使用@RequiredArgsConstructor注解时,它会自动为您生成一个构造方法,该构造方法会将remoteUserService作为参数传入并进行注入。这种方式是通过构造函数注入依赖。使用@RequiredArgsConstructor注解可以简化代码,减少手动编写构造方法的工作。
  2. @Autowired: 当在属性上使用@Autowired注解时,它会自动将相应类型的实例注入到该属性中。这种方式是通过字段注入依赖。Spring框架会自动扫描并查找与RemoteUserService类型匹配的实例,并将其注入到remoteUserService属性中。使用@Autowired注解可以方便地进行依赖注入,但需要确保所需的实例存在且唯一。

总体而言,这两种注入方式的效果是一样的,都会将

  1. RemoteUserService

注入到

  1. remoteUserService

属性中。选择使用哪种方式取决于偏好和项目中的约定。使用

  1. @RequiredArgsConstructor

可以提供更简洁的代码,而使用

  1. @Autowired

则更加灵活,可以适应更多不同的场景。

标签: 微服务 架构 Feign

本文转载自: https://blog.csdn.net/weixin_49561506/article/details/131653796
版权归原作者 小小印z 所有, 如有侵权,请联系我们删除。

“使用Feign进行微服务之间的接口调用:Spring Cloud Alibaba中的声明式服务调用”的评论:

还没有评论