SpringCloud Feign实现微服务间的远程调用(黑马头条Day04)

目录

Feign介绍

Feign的执行流程

项目中使用Feign介绍

实现步骤

添加Feign依赖

注册feign远程调用接口,并指定需要调用的微服务

在leadnews-artilce微服务中创建接口实现类

在wemedia微服务中添加@EnableFeignClients注解,并指定需要扫描的包

在wemedia微服务中注入article微服务中Feign接口的实现类,调用对应实现方法

远程调用服务降级

实现步骤

参考链接


Feign介绍

Feign是一个声明式的Web Service客户端。它让微服务之间的调用变得更简单。Feign具有可插拔式的注解支持,包括Feign 注解和JAX-RS注解。Feign还支持可插拔的编码器和解码器。Spring Cloud增加了对Spring MVC注解的支持,并且也支持Spring WebFlux。

在开发中,我们常用httpClient去远程调用其他系统的接口,需要我们指定调用的url(参考苍穹外卖中的调用支付等第三方接口),Feign 是一个声明式的 Web Service 客户端,它实现了一套远程调用的方法,调用的方式也更为优雅。

前提:1.被调用的模块注册到eureka中,能正常运行

2.feign接口文件夹要和启动类在同一个目录下, 否则需指定包名,@EnableFeignClients(basePackages="com.**.***")

Feign的执行流程

Feign在调用其他服务时,会根据注解中的url进行请求转发。它的工作原理是:

  1. 根据@FeignClient的value值找到服务,如果配置了服务注册中心,还会根据服务名获取服务实例列表。
  2. 构造请求参数,根据方法上的注解(如@PathVariable、@RequestParam、@RequestBody等)确定请求参数。
  3. 根据注解(@GetMapping、@PostMapping、@DeleteMapping等)确定请求方法和路径。
  4. 发起请求调用其他服务,获取结果。
  5. 封装结果,返回给调用方。

项目中使用Feign介绍

黑马头条作为一个典型的微服务项目,涉及到多个微服务,如上图中③媒体微服务,可以对用户发布的文章进行审核 ;②文章微服务,**在用户发布的文章经过媒体微服务审核后,利用文章微服务将其存储到文章相关表格中。**②和③对应的微服务之间并没有建立直接的联系,此时使用feign远程调用,在③中方便调用②中提供的服务。结构如下:

大致思路如下:

  1. 在feign-api(①)微服务中定义feign的接口,并通过@FeignClient(...)注解指定要调用的服务名称。
  2. 在article(②)微服务中创建feign接口的实现类,并实现具体业务逻辑,向文章相关表格中插入对应数据。
  3. 在wemedia(③)微服务中注入②中创建的接口的实现类,直接调用②中实现的方法。(面向接口编程)。

实现步骤

添加Feign依赖

bash 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

注册feign远程调用接口,并指定需要调用的微服务

java 复制代码
@FeignClient(value = "leadnews-article")
public interface IArticleClient {

    @PostMapping("/api/v1/article/save")
    public ResponseResult saveArticle(@RequestBody ArticleDto dto);
}

通过@FeignClient(...)注解指定要调用的微服务【leadnews-article(②)】,通过@PostMapping(...)注解指定其访问路径。

在leadnews-artilce微服务中创建接口实现类

java 复制代码
@RestController
@Slf4j
public class ArticleClient implements IArticleClient {

    @Autowired
    private ApArticleService apArticleService;
    /**
     * 修改或保存文章信息
     * @param dto
     * @return
     */
    @PostMapping("/api/v1/article/save")
    @Override
    public ResponseResult saveArticle(@RequestBody ArticleDto dto) {
        log.info("修改或保存文章信息:{}", dto);
        return apArticleService.saveArticle(dto);
    }
}

在wemedia微服务中添加@EnableFeignClients注解,并指定需要扫描的包

上图中指定扫描的包为basePackages = "com.heima.apis",由于Feign接口所在的包的微服务并不是调用者所在的微服务并不会扫描对应的包,需要指定。

在wemedia微服务中注入article微服务中Feign接口的实现类,调用对应实现方法

java 复制代码
@Autowired
    private IArticleClient iArticleClient;
    @Autowired
    
    /**
     * 审核成功,保存app端的相关文章数据
     * @param wmNews
     */
    private ResponseResult saveAppArticle(WmNews wmNews) {

        // ......

        ResponseResult responseResult = iArticleClient.saveArticle(dto);
        return responseResult;
    }

远程调用服务降级

服务降级:当服务调用失败或超时,我们需要有降级策略,避免影响整体系统。我们可以为Feign接口增加fallback指定降级实现类。

  • 服务降级是服务自我保护的一种方式,或者保护下游服务的一种方式,用于确保服务不会受请求突增影响变得不可用,确保服务不会崩溃

  • 服务降级虽然会导致请求失败,但是不会导致阻塞。

实现步骤

编写服务降级策略

java 复制代码
/**
 * feign失败配置
 */
@Component
public class IArticleClientFallback implements IArticleClient {
    @Override
    public ResponseResult saveArticle(ArticleDto dto) {
        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"保存数据失败");
    }
}

接口实现类所在的微服务中扫描服务降级所在的包,并通过@FeignClient(...)注解中的fallback属性指定服务降级的类。

java 复制代码
@Configuration
@ComponentScan("com.heima.apis.article.fallback")
public class InitConfig {
}

@FeignClient(value = "leadnews-article",fallback = IArticleClientFallback.class)
public interface IArticleClient {

    @PostMapping("/api/v1/article/save")
    public ResponseResult saveArticle(@RequestBody ArticleDto dto);
}

在调用者所在的微服务wemedia中添加具体超时设置

java 复制代码
feign:
  # 开启feign对hystrix熔断降级的支持
  hystrix:
    enabled: true
  # 修改调用超时时间
  client:
    config:
      default:
        connectTimeout: 2000
        readTimeout: 2000

其中connectTimeout指定连接超时,默认10s;readTimeout指定读取超时,默认60s。

参考链接

Feign实现远程接口的调用_feign远程调用接口的实现-CSDN博客

微服务服务间调用组件Feign使用介绍、原理、优化技巧-腾讯云开发者社区-腾讯云 (tencent.com)

相关推荐
黑马源码库miui520862 小时前
JAVA同城打车小程序APP打车顺风车滴滴车跑腿源码微信小程序打车源码
java·微信·微信小程序·小程序·uni-app
MadPrinter2 小时前
SpringBoot学习日记 Day11:博客系统核心功能深度开发
java·spring boot·后端·学习·spring·mybatis
dasseinzumtode2 小时前
nestJS 使用ExcelJS 实现数据的excel导出功能
前端·后端·node.js
淦出一番成就2 小时前
Java反序列化接收多种格式日期-JsonDeserialize
java·后端
Java中文社群2 小时前
Hutool被卖半年多了,现状是逆袭还是沉寂?
java·后端
程序员蜗牛3 小时前
9个Spring Boot参数验证高阶技巧,第8,9个代码量直接减半!
后端
yeyong3 小时前
咨询kimi关于设计日志告警功能,还是有启发的
后端
库森学长3 小时前
2025年,你不能错过Spring AI,那个汲取了LangChain灵感的家伙!
后端·openai·ai编程
爱吃苹果的日记本3 小时前
开学第一课
java
Java水解3 小时前
Spring Boot 启动流程详解
spring boot·后端