【SpringCloud】2.微服务的熔断和降级

news2024/11/25 14:37:37

目 录

    • 1. 熔 断
      • 1.1 发生场景
      • 1.2 熔断实现
      • 1.3 熔断测试
    • 2. 降 级
      • 2.1 发生场景
      • 2.2 降级处理
      • 2.3 降级测试

在 上篇博客,我们完成了项目的基本搭建工作,那这篇博客就来实现一下微服务的熔断和降级。

1. 熔 断

1.1 发生场景

在前面,我们用 springcloud-service-consumer 这个服务消费者调用 springcloud-service-provider 这个服务提供者的接口,现在我们假设一种情况,如果某天服务提供者宕机了,它的服务器坏掉不能及时为服务消费者提供正常服务,那会发生什么情况?大概是服务消费者调不通接口,它的日志会一堆报错,前端页面也会报错,如果流量大,整个系统可能会发生雪崩,将正常的服务消费者的服务也压垮掉。

面对这样的情况,我们就需要做熔断处理了,将不可用的服务提供者,暂时从整个系统中断开,以保证系统其它服务的正常可用。

1.2 熔断实现

将服务提供者从系统中断开后,原来服务消费者调用服务提供者的接口,改为由服务消费者自身直接返回结果。下面,我们在 springcloud-service-consumer 这个服务消费者中具体实现一下。

第一步,引入依赖

实现熔断,需要用到一个组件 Hystrix ,由于我这里用到的 openFeign 是 3.0.2 这个版本的,它没有集成 Hystrix ,所以需要额外在 springcloud-service-consumer 的 pom.xml 文件中加入对 Hystrix 的依赖。

<!-- 增加hystrix依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.2.7.RELEASE</version>
</dependency>

第二步,在properties配置文件中加配置

在 application.properties 配置文件中加入配置,以开启熔断支持

#开启服务熔断支持
feign.circuitbreaker.enabled=true

第三步,在启动类加上注解

在 SpringCloudServiceConsumerApplication.java 这个启动类上,加上注解 @EnableHystrix ,开启支持。

package com.yuhuofei;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @Description
 * @ClassName SpringCloudServiceConsumerApplication
 * @Author yuhuofei
 * @Date 2023/5/22 18:59
 * @Version 1.0
 */
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
public class SpringCloudServiceConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudServiceConsumerApplication.class, args);
    }
}

第四步,新建一个接口实现类

新建一个接口实现类 FeignServiceApiImpl.java 实现接口 FeignServiceApi.java ,内容如下所示

package com.yuhuofei.api;

import com.yuhuofei.entity.PersonInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description 接口回调实现类
 * @ClassName FeignServiceApiImpl
 * @Author yuhuofei
 * @Date 2023/6/18 11:12
 * @Version 1.0
 */
@Service
@Slf4j
public class FeignServiceApiImpl implements FeignServiceApi {

    @Override
    public List<PersonInfo> queryAllUser() {
        PersonInfo personInfo = new PersonInfo();
        personInfo.setId(0);
        personInfo.setName("服务暂时不可用,请稍后再试");
        personInfo.setPassWord("000000");

        List<PersonInfo> list = new ArrayList<>();
        list.add(personInfo);
        log.info("调用了熔断实现类,熔断返回信息{}", list);
        return list;
    }
}

第五步,更改接口注解信息

将接口 FeignServiceApi 的注解 @FeignClient(value = “springcloud-service-provider”) 改为 @FeignClient(value = “springcloud-service-provider”, fallback = FeignServiceApiImpl.class)

package com.yuhuofei.api;

import com.yuhuofei.entity.PersonInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

/**
 * @Description feign调用服务提供者的接口
 * @InterfaceName FeignServiceApi
 * @Author yuhuofei
 * @Date 2023/5/23 19:26
 * @Version 1.0
 */
@Service
@FeignClient(value = "springcloud-service-provider", fallback = FeignServiceApiImpl.class)
public interface FeignServiceApi {

    //调用服务提供者的接口
    @GetMapping("/provider/user/list")
    List<PersonInfo> queryAllUser();
}

到这里,所有的实现步骤就完成了,下面来测试一下结果。

1.3 熔断测试

我们依次启动注册中心和服务消费者的服务,作为模拟服务提供者宕机,所以不用启动服务提供者的服务。

在浏览器中,访问 http://localhost:8002/consumer/person/list-by-openfeign ,我们可以看到,前端页面能拿到做熔断后返回的信息。

在这里插入图片描述
服务消费者的后端日志,也能正常打印出来,没有报错。

在这里插入图片描述

2. 降 级

2.1 发生场景

还是以服务消费者的接口为例,前端通过调用接口 http://localhost:8002/consumer/person/list-by-openfeign 来获取列表信息,如果这个接口的逻辑处理比较复杂或者前端传的参数出现特殊情况,导致这个接口响应很慢或者超时,而同时又有很多请求在访问这个接口,并且这个接口又是后面所有业务流程的入口,那势必会影响业务的正常开展,这是其一。其二则是在这种糟糕的情况下,不断地请求还有可能会使系统奔溃,这种时候,就得考虑对这个接口做降级处理了。

2.2 降级处理

由于前面在 springcloud-service-consumer 这个服务消费者中,做熔断的时候,已经引入了 Hystrix 的依赖、在 properties 文件中加了配置、在启动类上加了注解 @EnableHystrix ,所以这里就不需要重复做这几步了。

接下来就是改造需要做降级的接口 http://localhost:8002/consumer/person/list-by-openfeign ,如下所示。

主要是在原来的 ConsumerController.java 类中做了两步

  • 第一步,新增了一个降级后的执行方法 personListFallBackMethod
  • 第二步,在原来的 getPersonListUseOpenFeign 方法上,新增一个注解 @HystrixCommand(fallbackMethod = “personListFallBackMethod”,
    commandProperties = {@HystrixProperty(name = “execution.isolation.thread.timeoutInMilliseconds”, value = “1500”)}),表示这个接口如果超过 1500 毫秒没有影响,则进行降级并调用降级后的方法。
package com.yuhuofei.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.yuhuofei.api.FeignServiceApi;
import com.yuhuofei.entity.PersonInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description
 * @ClassName ConsumerController
 * @Author yuhuofei
 * @Date 2023/5/23 18:55
 * @Version 1.0
 */
@RestController
@RequestMapping("/consumer/person")
@Slf4j
public class ConsumerController {

    public static final String PROVIDER_URL = "http://localhost:8001/";

    @Autowired
    private FeignServiceApi feignServiceApi;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/list")
    public List<PersonInfo> getPersonList() {
        return restTemplate.getForObject(PROVIDER_URL + "provider/user/list", List.class);
    }

    //设置降级后回调方法,设置超时降级策略,超时时间1500毫秒
    @HystrixCommand(fallbackMethod = "personListFallBackMethod",
            commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")})
    @GetMapping("/list-by-openfeign")
    public List<PersonInfo> getPersonListUseOpenFeign() {
        //为了模拟降级情况,设置线程睡眠2000毫秒
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            log.error("线程处理异常", e);
        }
        
        log.info("通过openfeign调用");
        List<PersonInfo>  list = feignServiceApi.queryAllUser();
        log.info("得到的列表:{}",list);
        return list;
    }

    //降级后,执行的方法
    private List<PersonInfo> personListFallBackMethod() {
        PersonInfo personInfo = new PersonInfo();
        personInfo.setId(-1);
        personInfo.setName("正常服务暂时不可用,已进行降级处理,请稍后再试");
        personInfo.setPassWord("111111");

        List<PersonInfo> list = new ArrayList<>();
        list.add(personInfo);
        log.info("调用了降级后的方法,降级后返回信息{}", list);
        return list;
    }
}

2.3 降级测试

一切改造工作完成后,我们依次启动注册中心、服务消费者的服务,然后在浏览器中调用 http://localhost:8002/consumer/person/list-by-openfeign 。

浏览器中,展示结果如下:

在这里插入图片描述

查看服务消费者的日志打印情况:

在这里插入图片描述
在这里插入图片描述

这里分析一下,先是打印线程处理异常,然后继续往下执行,打印通过openfeign调用,超时了,调用降级后要执行的方法并返回结果给前端,后端由于不是阻塞的,所以继续执行调用服务提供者的接口,调不通,最后走到了熔断类里面,流程上没问题,符合预期。

需要提一句的是,微服务的熔断和降级,无论是在服务消费者中还是服务提供者里面,都可以做都可以去实现,我这里只是以服务消费者为例进行了实现。

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

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

相关文章

【Java高级语法】(八)反射机制:有朋友问反射到底是怎样玩的?看完这篇文章你就清楚了~

Java高级语法详解之反射机制 :one: 概念:two: 优势和缺点:three: 使用3.1 Class类3.2 获取类的结构信息- 构造函数3.3 获取类的结构信息- 方法3.4 获取类的结构信息- 字段3.5 动态创建对象、调用方法和设置属性3.6 动态代理 :four: 底层原理:five: 应用场景:ear_of_rice: 总结:…

SedonaSQL 聚合函数使用说明

ST_Envelope_Aggr 函数说明: 返回几何的外边界 语法: ST_Envelope_Aggr (A:geometryColumn) 支持版本: v1.0.0 Spark SQL 举例说明: SELECT ST_Envelope_Aggr(pointdf.arealandmark) FROM pointdf运行示例(AggregateFunctionTest.java): ST_Intersection_Aggr 函数说明: …

大文件如何传输到电脑?亲测又快又简单!

我们平时可以因为各种原因&#xff0c;如更换新电脑、高清视频分享等&#xff0c;需要将大文件传输到另一台电脑上。大文件如何传输到电脑?相信这是很多朋友都想知道如何实现吧。我们为您提供了2种轻松将大文件从PC传输到PC的方法。话不多说&#xff0c;上技巧&#xff01; 方…

腾讯云服务器地域有什么区别?怎么选比较好

腾讯云服务器地域有什么区别&#xff1f;云服务器地域怎么选择&#xff1f;地域是指云服务器所在机房的地理位置&#xff0c;用户距离地域越近网络延迟越低&#xff0c;速度越快&#xff0c;所以地域就近选择即可。广州上海北京等地域网站域名需要备案&#xff0c;中国香港或其…

SpringBoot使用MockMVC单元测试Controller

前言&#xff1a; 在SpringBoot应用程序中&#xff0c;Controller是接受客户端请求并返回响应数据的核心组件。为了保证Controller的正确性和稳定性&#xff0c;我们可以使用MockMVC框架进行单元测试。MockMVC是Spring框架提供的一个HTTP客户端&#xff0c;用于模拟HTTP请求和响…

2023年智能优化算法之——增长优化器Growth Optimizer(GO),附MATLAB代码

增长优化器的主要设计灵感来源于个人在社会成长过程中的学习和反思机制。学习是个体通过从外部世界获得知识而成长的过程。反思是检查个人自身不足并调整个人学习策略以帮助个人成长的过程。参考文献如下&#xff1a; Zhang, Qingke, et al. “Growth Optimizer: A Powerful M…

二维码在固定资产实物盘点中的应用

很多企业为了掌握固定资产的后续使用情况和状态&#xff0c;会定期对投入使用的固定资产进行盘点&#xff0c;然而固定资产常会出现分散情况&#xff0c;在这种情况下让财务人员到达每个固定资产的所在处进行实地盘点显得极为不现实。 也有不少企业会在盘点过程中使用到固定资…

聊天室(一)___常见的基本功能实现

最近搞聊天室的人还挺多&#xff0c;正好自己也弄就总结自己遇到必不可少的一些功能&#xff0c;本篇文章主要为自己和看到我文章的人一种思路&#xff0c;希望大家不要把聊天室想的太复杂。 上图是我自己做的一个聊天室&#xff0c;类似微信的单聊群聊收藏等功能&#xff0c;根…

python+requests接口自动化框架详解,没有比这个更详细的了

目录 为什么要做接口自动化框架 正常接口测试的流程是什么&#xff1f; 一、接口框架如下&#xff1a; 二、接口的数据规范设计---Case设计 2.1注册接口用例 2.2登录接口用例 三、创建utils包&#xff1a;用来存放公共的类 3.1 ParseExcel.py 操作封装excel的类&#xf…

【AI工具】-Stable Diffusion本地化部署教程

前言 今天我们要介绍的是时下最流行的AI绘图软件Stable Diffusion&#xff0c;虽然Diffusion.ai已经开放api&#xff0c;但是长时间的商业化调用我们需要购买很多的金币。所以我们需要找一个平替的AI绘图平台&#xff0c;现在主流市场中AI绘图软件主要就是OpenAI的DALLE、midj…

SSM会议管理系统

SSM会议管理系统 后端基于SSM、前端基于Freemarker写的会议管理系统、使用JDK8、mysql使用5.7版本 技术栈 Spring SpringMVC MyBatis Mysql Freemarker jqueryajax[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JGo0luHu-1687163482019)(img.png)] …

【Python 随练】打印水仙花数

题目&#xff1a; 打印出所有的"水仙花数"&#xff0c;所谓"水仙花数"是指一个三位数&#xff0c;其各位数字立方和等于该数 简介&#xff1a; 在本篇博客中&#xff0c;我们将解决一个经典的数学问题&#xff1a;打印出所有的水仙花数。水仙花数是指一…

Unity核心5——Tilemap

Tilemap 一般称之为瓦片地图或者平铺地图&#xff0c;是 Unity2017 中新增的功能&#xff0c;主要用于快速编辑 2D 游戏中的场景&#xff0c;通过复用资源的形式提升地图多样性 ​ 工作原理就是用一张张的小图排列组合为一张大地图 ​ 它和 SpriteShape 的异同 共同点&#x…

浅析GPT2中的autoregressive和BERT的autoencoding源码实现

经常使用BERT来做研究&#xff0c;因此对Encoder的架构较为熟悉&#xff0c;但是从来没有了解过GPT这样的Decoder架构&#xff0c;尤其对自回归的形式不知道源码是如何实现的。 为了方便对比和讨论&#xff0c;接来下所探讨的源码都是基于HuggingFace这个框架的。 Bert注意力…

基于亚马逊云科技Serverless,朝夕光年和Second Dinner携手打造年度手游

经典的漫威IP&#xff0c;酷炫的卡牌对战&#xff0c;丰富的故事情节&#xff0c;这款移动游戏《MARVEL SNAP》一经上线就深得全球玩家喜爱。在The Game Awards 2022的年度颁奖典礼上&#xff0c;它更是以出色的表现&#xff0c;一举斩获最佳移动游戏奖项。 其研发公司Second …

【ElasticSearch】中文分词器

ES默认的analyzer&#xff08;分词器&#xff09;&#xff0c;对英文单词比较友好&#xff0c;对中文分词效果不好。不过ES支持安装分词插件&#xff0c;增加新的分词器。 1、如何指定analyzer&#xff1f; 默认的分词器不满足需要&#xff0c;可以在定义索引映射的时候&#…

Python自动办公之合并多个PDF文件

本文基于使用pycharm平台&#xff0c;使用glob库和PyPDF2库实现 首先将需要合并的文件放于一个文件中 如下图 addpdf文件夹为需要合并的文件位置 good.py为代码块 代码如下 print(这个小代码仅仅用于合并pdf文件数量小于10的情况) print() from PyPDF2 import PdfMerger,P…

深度解析DuckDB的ScheduleEvents

深度解析DuckDB的ScheduleEvents 1.ScheduleEventData2.ScheduleEventsInternal3.SchedulePipeline 3.1 Event3.2 PipelineEventStack3.3 主逻辑4.可视化总结 书接上回熬夜三晚之深度解析DuckDB MetaPipeline&#xff0c;MetaPipeline在初始化的时候会构建出下面几个&#xff1…

【ARMv8/v9 异常模型入门及渐进2 - 系统控制寄存器 SCTRL_ELx 介绍】

文章目录 SCTRL_ELx 介绍背景ARMv8 SCTLR_ELx 介绍ARMv9 SCTLR_ELx 介绍 SCTRL_ELx 介绍背景 由于在做DFD 测试过程中需要测试 EL1 状态下的 self-hosted trace 功能&#xff0c;但是这个测试是在UEFI中做的&#xff0c;在开发验证阶段UEFI默认是运行在EL3 下的&#xff0c;所…

mac安装VsCode遇到的问题

万事开头难&#xff0c;头一次在安装生产工具的时候&#xff0c;就遇到了这么棘手的问题。百度和Google都试过了&#xff0c;网上的所有方式对我都没效果。最终自己阴差阳错解决了&#xff0c;我看内外网反馈这个问题的还挺多&#xff0c;在这里记录一下&#xff0c;希望可以帮…