【Spring Cloud】声明性REST客户端:Feign

Spring Cloud Feign ——fallback 服务降级

  • 1. Feign 简介
  • 2. Feign 的基础使用
    • 2.1 普通 HTTP 请求
    • 2.2 Feign 远程调用上传文件接口

1. Feign 简介

Feign 是一个声明式的 HTTP 客户端,它简化了编写基于 REST 的服务间通信代码的过程。在 Spring Cloud 中,Feign 扮演着重要的角色,它具有可插入注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器解码器Spring Cloud增加了对Spring MVC注释的支持,并使用Spring Web中默认使用的HttpMessageConverters。Spring Cloud 集成RibbonEureka或者Nacos 注册中心 以在使用 Feign 时提供负载均衡的http 客户端。

Feign 特性介绍:

  • 声明式 REST 客户端
    Feign 允许开发者使用接口和注解的方式定义对远程 REST 服务的调用,而不需要关心底层的 HTTP 请求和响应处理。在 Feign 中,可以通过接口方法的定义来描述远程服务的各种操作,包括 URL、请求方法、参数等信息。
  • 集成负载均衡
    通过整合 Ribbon 负载均衡器,Feign 可以自动实现对指定服务的负载均衡调用。这使得在服务提供者有多个实例的情况下,Feign 可以根据负载均衡策略选择合适的服务实例进行调用。
  • 支持多种请求方法
    Feign 支持各种 HTTP 请求方法,如 GETPOSTPUTDELETE 等,从而使得对远程服务的调用变得非常灵活。
  • 动态 URL 和参数绑定
    使用 Feign,可以将参数绑定到 URL 模板中,并将动态的数据传递给远程服务。同时,Feign 也支持将参数绑定到请求体中,以便进行 POSTPUT 请求。
  • 集成 Hystrix 容错机制
    结合 Spring Cloud 中的 Hystrix 断路器,Feign 可以提供对远程服务调用的容错能力,包括超时、断路器等功能,从而增强了服务调用的可靠性。
  • 易于集成
    在 Spring Cloud 应用程序中,Feign 与其他组件(如 EurekaZuul 等)无缝集成,通过简单的依赖配置和注解即可快速启用,并且无需额外的繁琐配置。

总之,Spring Cloud Feign 提供了一种简洁而优雅的方式来定义和调用 REST 服务,它简化了服务间通信的过程,提高了开发效率,为构建微服务架构的应用程序提供了便利的支持。

2. Feign 的基础使用

搭建一个 SpringCloud 的 Demo,包含生产者和消费者。 都是普通的 web 服务,其中 消费者 比生产者多了 Feign 的依赖。

        <!-- SpringCloud Openfeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

并且在启动类上添加注解:@EnableFeignClients
如果配置了fallbackFactory降级,则还需要引入依赖:

        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>

然后在启动类上添加注解:@EnableHystrix,并且添加开启服务降级的配置:

feign:hystrix:enabled: true

2.1 普通 HTTP 请求

其中生产者提供一个POST 的接口:/student/queryList 查询数据库中 student 表的数据。

@RestController
@RequestMapping("/student")
public class StudentController {@Resourceprivate IStudentService studentService;@GetMapping("/queryList")public ApiR queryList(){List<Student> studentList = studentService.list();return ApiR.ok().data(studentList);}
}

消费者使用 Feign 远程调用这个查询列表的接口:

首先新建一个 @FeignClient 注解的接口

import com.lin.common.config.FeignSupportConfig;
import com.lin.common.constant.ServiceNameConstants;
import com.lin.common.vo.ApiR;
import com.lin.consumer.feign.fallback.RemoteStudentServiceFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;/*** @author linmengmeng* @since 2023/11/12 14:12*/
@FeignClient(contextId = "RemoteStudentService", name = ServiceNameConstants.PROVIDER_SERVICE, configuration = FeignSupportConfig.class, fallbackFactory = RemoteStudentServiceFallback.class)
public interface RemoteStudentService {@GetMapping ("/student/queryList")ApiR queryList();
}

我这里将生产者和消费者都注册到 Nacos 上,所以这里可以直接配置name = ServiceNameConstants.PROVIDER_SERVICE 通过生产者的服务名,直接调用对方的接口。

并配置了降级回调 fallbackFactory = RemoteStudentServiceFallback.class,降级操作是实现了上面定义的接口,并输出具体的异常信息;

import com.lin.common.vo.ApiR;
import com.lin.consumer.feign.RemoteStudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;/*** @author linmengmeng* @since 2023/11/12 14:22*/
@Slf4j
@Component
public class RemoteStudentServiceFallback implements FallbackFactory<RemoteStudentService> {@Overridepublic RemoteStudentService create(Throwable cause) {log.error("RemoteStudentServiceFallback error : {}", cause.getMessage());return () -> {log.error("sayHello error 接口调用异常");return ApiR.fail();};}
}

添加一个测试请求接口,调用上面的 feign 接口:

import cn.hutool.json.JSONUtil;
import com.lin.common.vo.ApiR;
import com.lin.common.vo.R;
import com.lin.consumer.feign.RemoteStudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** 测试* @author linmengmeng* @since 2023/11/8 14:18*/
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {@Resourceprivate RemoteStudentService remoteStudentService;@GetMapping("/sayHello")public R sayHello() {log.info("sayHello。。。。。。");ApiR apiR = remoteStudentService.queryList();log.info("接口调用结果-apiR:{}", JSONUtil.toJsonStr(apiR));return R.ok();}
}

先启动消费者,然后使用 Postman 调用消费者的 sayHello接口,可以看到,这个接口里面调用了Feign的远程接口,这时候生产者没启动,服务接口queryList肯定会掉不通的,按照原来 OkHTTP 的调用,远程接口异常,会将异常传递到接口调用方。经过上面的配置,我们来调用接口看下:
在这里插入图片描述
可以看到,接口正常响应了,接着看下消费者的日志:

2023-11-12 22:18:11.504  INFO [io-37002-exec-1] [] c.l.consumer.controller.TestController   [29] : sayHello。。。。。。
2023-11-12 22:18:12.030  WARN [reakerFactory-1] [] o.s.c.l.core.RoundRobinLoadBalancer      [97] : No servers available for service: cloud-feign-provider
2023-11-12 22:18:12.033  WARN [reakerFactory-1] [] .s.c.o.l.FeignBlockingLoadBalancerClient [103] : Load balancer does not contain an instance for the service cloud-feign-provider
2023-11-12 22:18:12.065 ERROR [reakerFactory-1] [] c.l.c.f.f.RemoteStudentServiceFallback   [18] : RemoteStudentServiceFallback error : [503] during [POST] to [http://cloud-feign-provider/student/queryList] [RemoteStudentService#queryList()]: [Load balancer does not contain an instance for the service cloud-feign-provider]
2023-11-12 22:18:12.072 ERROR [reakerFactory-1] [] c.l.c.f.f.RemoteStudentServiceFallback   [20] : sayHello error 接口调用异常
2023-11-12 22:18:12.204  INFO [io-37002-exec-1] [] c.l.consumer.controller.TestController   [31] : 接口调用结果-apiR:{"code":500,"message":"系统繁忙,请稍后再试!","data":{"changeLog":"","detail":{},"releaseTime":"2023-11-12 22:18:12"}}

可以看到,在接口调用成功后,调用Feign远程接口时,打印了两行 Warn 日志,提示我们生产者服务未找到,然后打印了我们的降级服务里面的error日志,并且我们用postman请求的接口正常响应了。

这就跟我们之前使用 OkHttp 远程调用接口有区别了,这里虽然上游服务异常,但是并不影响我们这边的调用,对于消费者来说,自身有个闭环的逻辑,不会将异常传递到本身,我们的业务逻辑中可以正常获取到降级服务的结果及日志。

接着分别启动生产者的服务,再次调用消费者的接口:

2023-11-12 22:31:50.722  INFO [io-37002-exec-2] [] c.l.consumer.controller.TestController   [29] : sayHello。。。。。。
2023-11-12 22:31:51.312  INFO [io-37002-exec-2] [] c.l.consumer.controller.TestController   [31] : 接口调用结果-apiR:{"code":200,"message":"成功","data":[{"id":"001","name":"Tom","age":19,"createTime":"2023-11-12T21:19:15"},{"id":"002","name":"Mary","age":18,"createTime":"2023-11-12T21:19:39"}]}

可以看到,接口正常响应了,数据也拿到了。

2.2 Feign 远程调用上传文件接口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/169779.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

删除杀软回调 bypass EDR 研究

01 — 杀软或EDR内核回调简介 Windows x64 系统中&#xff0c;由于 PatchGuard 的限制&#xff0c;杀软或EDR正常情况下&#xff0c;几乎不能通过 hook 的方式&#xff0c;完成其对恶意软件的监控和查杀。那怎么办呢&#xff1f;别急&#xff0c;微软为我们提供了其他的方法&a…

2352 智能社区医院管理系统JSP【程序源码+文档+调试运行】

摘要 本文介绍了一个智能社区医院管理系统的设计和实现。该系统包括管理员、护工和医生三种用户&#xff0c;具有社区资料管理、药品管理、挂号管理和系统管理等功能。通过数据库设计和界面设计&#xff0c;实现了用户友好的操作体验和数据管理。经过测试和优化&#xff0c;系…

Spring -Spring之依赖注入源码解析(下)--实践(流程图)

IOC依赖注入流程图 Autowired&#xff1a;注入的顺序及优先级&#xff1a;type-->Qualifier-->Primary-->PriOriry-->name Resource&#xff1a;先通过Resource上指定的byName进行注入&#xff0c;若byName没找到&#xff0c;则与Autowired注入方式相同&#xff…

腾讯域名优惠卷领取

腾讯域名到到期了&#xff0c;听说申请此计划&#xff0c;可获得优惠卷&#xff0c;看到网上5年域名只需要10元&#xff0c;姑且试试看。 我的博客即将同步至腾讯云开发者社区&#xff0c;邀请大家一同入驻&#xff1a;https://cloud.tencent.com/developer/support-plan?in…

【Java 进阶篇】JQuery DOM操作:轻松驾驭网页内容的魔法

在前端开发的舞台上&#xff0c;DOM&#xff08;文档对象模型&#xff09;是我们与网页内容互动的关键。而JQuery作为一个轻量级的JavaScript库&#xff0c;为我们提供了便捷而强大的DOM操作工具。在本篇博客中&#xff0c;我们将深入探讨JQuery的DOM内容操作&#xff0c;揭开这…

【408】计算机学科专业基础 - 数据结构

数据结构知识 绪论 数据结构在学什么 如何用程序代码把现实世界的问题信息化 如何用计算机高效地处理这些信息从而创造价值 数据结构的基本概念 什么是数据&#xff1a; 数据是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序…

ElasticSearch知识点

什么是ElasticSearch ElasticSearch: 智能搜索&#xff0c;分布式的搜索引擎&#xff0c;是ELK的一个非常完善的产品&#xff0c;ELK代表的是: E就是ElasticSearch&#xff0c;L就是Logstach&#xff0c;K就是kibana Elasticsearch是一个建立在全文搜索引擎 Apache Lucene基础…

20231112_DNS详解

DNS是实现域名与IP地址的映射。 1.映射图2.DNS查找顺序图3.DNS分类和地址4.如何清除缓存 1.映射图 图片来源于http://egonlin.com/。林海峰老师课件 2.DNS查找顺序图 3.DNS分类和地址 4.如何清除缓存

面向切面编程AOP

2023.11.12 本章学习spring另一大核心——AOP。AOP是一种编程技术&#xff0c;底层是使用动态代理来实现的。Spring的AOP使用的动态代理是&#xff1a;JDK动态代理 CGLIB动态代理技术。Spring在这两种动态代理中灵活切换&#xff0c;如果是代理接口&#xff0c;会默认使用JDK动…

OSG练习:模仿Ventsim制作三维矿井智能通风系统

1、效果 2、计划内容 1) 三维场景的加载显示;已实现 2)矿井巷道建模及纹理;已实现 3)矿井基础数据采集及修正;已实现 4)通风网络解算算法;已实现 5)通风设备及设施模型制作;未实现 6)风流模拟效果 ;进行中 7)火灾模拟效果;未实现 8)巷道属性查看栏;未实现 9)…

PCA(主成分分析)数据降维技术代码详解

引言 随着大数据时代的到来&#xff0c;我们经常会面临处理高维数据的问题。高维数据不仅增加了计算复杂度&#xff0c;还可能引发“维度灾难”。为了解决这一问题&#xff0c;我们需要对数据进行降维处理&#xff0c;即在不损失太多信息的前提下&#xff0c;将数据从高维空间…

openstack部署后实战

分布式部署规则 1、平常都是两台Node安装OpenStack平台&#xff0c;那如果想分布式部署该怎么做&#xff1f;比如&#xff1a;部署两台Nova服务&#xff0c;一台单独的Neutron服务&#xff0c;一台单独的存储节点等。 整体思想&#xff1a; 如果想要部署两台Nova服务&#xf…