【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.mzph.cn/news/139807.shtml

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

相关文章

【论文阅读】PSDF Fusion:用于动态 3D 数据融合和场景重建的概率符号距离函数

【论文阅读】PSDF Fusion&#xff1a;用于动态 3D 数据融合和场景重建的概率符号距离函数 Abstract1 Introduction3 Overview3.1 Hybrid Data Structure3.2 3D Representations3.3 Pipeline 4 PSDF Fusion and Surface Reconstruction4.1 PSDF Fusion4.2 Inlier Ratio Evaluati…

AI爆文变现脚本:易用且免费的自动写作脚本更新了

之前给大家分享的AI爆文变现写作脚本 由于时间仓促&#xff0c;加上我对很多东西不熟悉 免费版本对新手小白来说&#xff0c;安装部署起来是非常的困难 于是这几天我加班加点把整个软件的部署简化 现在无需复杂的环境配置安装&#xff0c;下载配置下就可以使用了。 免费版…

[工业自动化-16]:西门子S7-15xxx编程 - 软件编程 - 西门子仿真软件PLCSIM

目录 前言&#xff1a; 一、PLCSIM仿真软件 1.1 PLCSIM仿真软件基础版&#xff08;内嵌&#xff09; 1.2 PLCSIM仿真软件与PLCSIM仿真软件高级版的区别&#xff1f; 1.3 PLCSIM使用 前言&#xff1a; PLC集成开发环境是运行在Host主机上&#xff0c;Host主机与PLC可以通过…

音视频基础知识

图像&#xff08;YUV RGB&#xff09; ​​​​​​​​​​​​​​这个讲的比较好 RGB颜色编码 图像显示主要是由像素组成&#xff0c;每个像素点的颜色组成都是采用RGB格式&#xff0c;RGB就是红、绿、蓝&#xff0c;RGB分别取不同的值&#xff0c;展示不同的颜色。 YUV…

二十五、W5100S/W5500+RP2040树莓派Pico<Modebus TCP Server示例>

文章目录 1 前言2 简介2 .1 什么是Modbus TCP&#xff1f;2.2 Modbus TCP指令介绍2.3 请求数据过程2.4 Modbus TCP协议优点2.5 Modbus TCP应用场景 3 WIZnet以太网芯片4 Modbus TCP示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意…

阿里云OSS和腾讯云COS对象存储介绍和简单使用

对象存储指的是一种云存储服务&#xff0c;其主要是将数据以对象的形式存储在云端&#xff0c;并且提供了完全的API调用&#xff0c;这些API包括上传&#xff0c;下载&#xff0c;删除&#xff0c;复制&#xff0c;预览&#xff0c;权限设置等等。OSS对象存储和COS对象存储都是…

设计模式之十一:代理模式

代理可以控制和管理访问。 RMI提供了客户辅助对象和服务辅助对象&#xff0c;为客户辅助对象创建和服务对象相同的方法。RMI的好处在于你不必亲自写任何网络或I/O代码。客户程序调用远程方法就和运行在客户自己本地JVM对对象进行正常方法调用一样。 步骤一&#xff1a;制作远程…

js案例:打地鼠游戏(打灰太狼)

效果预览图 游戏规则 当灰太狼出现的时候鼠标左键点击灰太狼加10分&#xff0c;小灰灰出现的时候鼠标左键点小灰灰击减10分&#xff0c;不点击不减分不加分。 整体思路 1.把获取背景图片中每个地洞的位置&#xff0c;把所有位置放到一个数组中。 2.封装随机数函数&#xff0c;随…

腾讯域名优惠卷领取

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

【hacker送书第一期】嵌入式虚拟化技术与应用

第一期图书推荐 前言为什么嵌入式系统需要虚拟化技术&#xff1f;专家推荐本书适用群体内容简介目录权威作者团队参与方式 前言 随着物联网设备的爆炸式增长和万物互联应用的快速发展&#xff0c;虚拟化技术在嵌入式系统上受到了业界越来越多的关注、重视和实际应用。嵌入式系…

Win10专业版安装wsl-ubuntu子系统

文章目录 一、查看是否满足安装要求二、管理员权限启动 Windows PowerShell三、启用Windows10子系统功能四、启用虚拟机平台功能五、重启电脑六、下载 Linux 内核更新包&#xff08;适用于 x64 计算机的 WSL2 Linux 内核更新包&#xff09;七、将 WSL 2 设置为默认版本八、打开…

关于session的不断变化问题

今天在帮同学解决一个小问题&#xff0c;差点阴沟翻船。 问题再现&#xff1a;他从github上拉了一个项目下来跑&#xff0c;结果发生跑不通问题出现在验证码一直不对。 我一看项目源码&#xff0c;验证码生成后存储再session中了&#xff0c;等用户发送请求验证的时候sessionI…

「帝国风暴兵」加入 The Sandbox,推出真实的全新人物化身系列和体验!

我们很高兴宣布与流行文化中最具标志性的娱乐品牌 Shepperton 设计工作室的「帝国风暴兵」达成合作伙伴关系。这一合作标志着该科幻品牌首次进入元宇宙&#xff0c;让风暴兵的粉丝们以全新的方式体验「帝国风暴兵」。 在这个体验中&#xff0c;玩家将置身于帝国风暴兵的营地&am…

数据分析实战 | 泊松回归——航班数据分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 八、模型评价 一、数据及分析对象 CSV文件&#xff1a;o-ring-erosion-only.csv 数据集链接&#xff1a;https://download.csdn.net/download/m0_7…

基于 Gin 的 HTTP 代理 demo

上次用 TCP 模拟了一个 HTTP 代理之后&#xff0c;感觉那样还是太简陋了&#xff0c;想着是不是可以用框架来做一个有点实际用处的东西。所以&#xff0c;就思索如何用 golang 的 Gin 框架来实现一个&#xff1f;嗯&#xff0c;对的你没有听错&#xff0c;是 gin 框架。你可能会…

Java 数据结构篇-实现双链表的核心API

&#x1f525;博客主页&#xff1a; 小扳_-CSDN博客 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 双链表的说明 1.1 双链表 - 创建 1.2 双链表 - 根据索引查找节点 1.3 双链表 - 根据索引插入节点 1.4 双链表 - 头插节点 1.5 双链表 - 尾插 1.6 双链表 - 根据索引来…

Dell戴尔灵越Inspiron 7700 AIO一体机电脑原厂预装Windows10系统

链接&#xff1a;https://pan.baidu.com/s/1-slgR9t4Df_eko0Y6xaeyw?pwdmk0p 提取码&#xff1a;mk0p 灵越7700一体机原装出厂系统自带声卡驱动、无线网卡驱动、面部识别等所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、MyDell等预装程序 由于时间关系,…

Linux如何修改主机名(hostname)(亲测可用)

文章目录 背景Linux如何修改主机名&#xff08;hostname&#xff09;方法方法1. 使用 hostnamectl 命令示例 2. 编辑 /etc/hostname 文件注意事项 背景 我创建虚拟机的时候没设置主机名&#xff0c;现在显示localhost&#xff0c;有点尴尬&#x1f605;&#xff1a; 需要重新设…

冒泡排序

贵阳这个地方的天气变化好大呀&#xff0c;前两天晒大太阳&#xff0c;今天就冷的脚抖&#xff0c;简直不要太冷&#xff0c;但是不管怎么样&#xff0c;还是要学习的哟&#xff01; 冬天来了&#xff0c;春天确实还有一点远&#xff01; 好了&#xff0c;话不多说&#xff0c;…

SpringBoot 缓存之 @Cacheable 详细介绍

一、简介 1、缓存介绍 Spring 从 3.1 开始就引入了对 Cache 的支持。定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术。并支持使用 JCache&#xff08;JSR-107&#xff09;注解简化我们的开发。&#xfeff; 其…