SpringCloud入门实战(七)-Hystrix服务降级

news2024/9/24 3:24:05

📝 学技术、更要掌握学习的方法,一起学习,让进步发生
👩🏻 作者:一只IT攻城狮 。
💐学习建议:1、养成习惯,学习java的任何一个技术,都可以先去官网先看看,更准确、更专业。
💐学习建议:2、然后记住每个技术最关键的特性(通常一句话或者几个字),从主线入手,由浅入深学习。
❤️ 《SpringCloud入门实战系列》解锁SpringCloud主流组件入门应用及关键特性。带你了解SpringCloud主流组件,是如何一战解决微服务诸多难题的。项目demo:源码地址

👉🏻 👉🏻 👉🏻 SpringCloud 入门实战系列不迷路 👈🏻 👈🏻👈🏻:

  • SpringCloud 入门实战(一)什么是SpringCloud?
  • SpringCloud 入门实战(二)-SpringCloud项目搭建
  • SpringCloud 入门实战(三)-Eureka注册中心集成
  • SpringCloud入门 实战(四)-Zookeeper、Consul注册中心集成
  • SpringCloud入门实战(五)-Ribbon负载均衡集成
  • SpringCloud入门实战(六)-OpenFeign服务调用集成
  • SpringCloud入门实战(七)-Hystrix入门简介
  • SpringCloud入门实战(七)-Hystrix服务降级
  • SpringCloud入门实战(七)-Hystrix服务熔断
  • SpringCloud入门实战(七)-Hystrix服务限流
  • SpringCloud入门实战(七)-Hystrix Dashboard图形化监控

文章目录

  • 一、Hystrix服务降级
  • 二、服务端降级
    • 1、引入Hystrix依赖
    • 2、案例演示
    • 3、服务端如何降级
      • 1)启动类添加激活注解:
      • 2)业务类方法上添加启用:@HystrixCommand(fallbackMethod = "fallback")
  • 三、客户端降级
    • 1、引入Hystrix依赖
    • 2、启动类添加激活注解@EnableHystrix
    • 3、改yml
    • 4、业务类方法上添加启用:@HystrixCommand(fallbackMethod = "fallback")
  • 四、全局通用服务降级
    • 1、类上加注解:DefaultProperties(defaultFallback=" ")指定全局兜底方法
    • 2、方法加注解:@HystrixCommand
    • 3、编写全局降级方法
  • 五、解耦服务降级
    • 1、新建一个解耦降级处理类
    • 2、Feign客户端定义的接口添加fallback

Hystrix关键特性:服务降级、服务熔断、服务限流

一、Hystrix服务降级

服务降级:也就是假设对方系统不可用了,向调用方返回一个符合预期的,可备选的响应。比如我们常见的“服务器忙,请稍后重试!”、“系统开小差,请稍后再试!”、“您的内容飞到了外太空…”等,超时不再等待,出错有兜底方案。不用客户等待并立刻返回一个友好的提示,这就是服务降级。

出现服务降级的情况
①程序运行异常;
②超时;
③服务熔断触发服务降级;
④线程池/信号量打满也会导致服务降级。

解决方案
对方服务超时了或宕机,调用者不能一直卡死等待,必须有服务降级;
对方服务可能OK,调用者自己出故障或有自我要求(自己的等待时间小于服务提供者),自己服务降级。

二、服务端降级

在springcloud项目中,技术实现上来说Hystrix服务降级放在服务端、客户端均可以,具体根据自己的业务场景判定,但是一般Hystrix服务降级fallback是放在客户端,这里我们均演示一下。

项目结构:

在这里插入图片描述

父工程的版本环境:

 <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>2021.0.3</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>2.2.7.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.7.1</version>
        <type>pom</type>
        <scope>import</scope>
</dependency>

1、引入Hystrix依赖

首先服务端(也就是我们的payment工程)引入hystrix依赖(具体版本根据自己环境决定):

   <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.hystrix</groupId>
            <artifactId>hystrix-javanica</artifactId>
            <version>1.5.18</version>
    </dependency>

2、案例演示

Controller类代码:

@RestController
@RequestMapping("/payment")
@Slf4j
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @GetMapping(value = "/hystrix/ok/{id}")
    public String paymentInfoOk(@PathVariable("id") Integer id) {
        String result = paymentService.paymentInfoOk(id);
        log.info("========result:{}========", result);
        return result;
    }
    @GetMapping(value = "/hystrix/timeout/{id}")
    public String paymentInfoTimeOut(@PathVariable("id") Integer id) {
        String result = paymentService.paymentInfoTimeOut(id);
        log.info("========result:{}========", result);
        return result;
    }
}

服务端业务类简单编写两个方法:一个正常查询方法,一个模拟复查业务耗时的方法:

@Service
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentService {

    @Override
    public String paymentInfoOk(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + "成功访问paymentInfoOK,id=" + id;
    }

    @Override
    public String paymentInfoTimeOut(Integer id) {
        int time = 5;
        try {
            TimeUnit.SECONDS.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() +  "耗时" + time + "秒成功访问paymentInfoTimeOut,id=" + id;
    }
}

简单测试:两个接口都正常访问和返回:
http://localhost:8001/payment/hystrix/ok/1 直接返回
http://localhost:8001/payment/hystrix/timeout/1 等待5s返回(转圈圈一下)

并发请求:接下来通过jmeter压测接口:http://localhost:8001/payment/hystrix/timeout/1,模拟2w个请求访问我们的paymentInfoTimeOut耗时业务接口。

现象:发现两个接口都会转圈甚至卡死,我们发现正常直接返回结果的接口也会被同一个微服务里耗时接口拖垮。所以想要系统高可用必须降级处理。假设payment服务端业务逻辑实际处理需要5s,微服务对自身有要求,超过3s作超时处理,也是需要降级的。

原因:SpringBoot默认集成的是tomcat,tomcat的默认工作线程(10个)被打满了,没有多余的线程来分解压力和处理。

3、服务端如何降级

1)启动类添加激活注解:

@EnableCircuitBreaker

有的环境会提示@EnableCircuitBreaker is deprecated已弃用,用@EnableHystrix注解代替即可。

本demo环境使用的是@EnableHystrix激活注解

2)业务类方法上添加启用:@HystrixCommand(fallbackMethod = “fallback”)

在fallbackMethod中添加一个方法,value设置为超时时间,当超过超时时间时,就会调用备用的方法

注:降级(FallBack)方法必须与其对应的业务方法在同一个类中,否则无法生效。

@RestController
@RequestMapping("/payment")
@Slf4j
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @GetMapping(value = "/hystrix/ok/{id}")
    public String paymentInfoOk(@PathVariable("id") Integer id) {
        String result = paymentService.paymentInfoOk(id);
        log.info("========result:{}========", result);
        return result;
    }
    //设置超时时间3s
    @HystrixCommand(fallbackMethod = "fallback",commandProperties = {
            @HystrixProperty(name ="execution.isolation.thread.timeoutInMilliseconds",value = "3000")
    })
    @GetMapping(value = "/hystrix/timeout/{id}")
    public String paymentInfoTimeOut(@PathVariable("id") Integer id) {
        String result = paymentService.paymentInfoTimeOut(id);
        log.info("========result:{}========", result);
        return result;
    }
    public String fallback(Integer id){
        return "系统繁忙,请稍后再试!线程池:" + Thread.currentThread().getName() +"访问paymentInfoTimeOut,id=" + id;

    }
}

测试降级效果:

不会再等待5s,到达设置的超时时间3s就会调用降级方法。

Tip:如果不设置超时时间,Hystrix默认超时时间是1秒,我们可以通过hystrix源码看到:找到 hystrix-core.jar包下的HystrixCommandProperties类中的default_executionTimeoutInMilliseconds属性局势默认的超时时间:1000

三、客户端降级

我们将服务端payment工程刚做的操作恢复到没有任何降级处理的状态,开始演示客户端降级。

1、引入Hystrix依赖

客户端工程order同样的操作引入Hystrix依赖:

  <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
           <version>2.2.1.RELEASE</version>
       </dependency>
       <dependency>
           <groupId>com.netflix.hystrix</groupId>
           <artifactId>hystrix-javanica</artifactId>
           <version>1.5.18</version>
   </dependency>

2、启动类添加激活注解@EnableHystrix

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
@EnableHystrix
public class CloudOrder {
    public static void main(String[] args) {
        SpringApplication.run(CloudOrder.class, args);
    }
}

3、改yml

我们的客户端是通过feign调用服务端,所以在order工程中修改yml,添加内容:

feign:
  hystrix:
    enabled: true

4、业务类方法上添加启用:@HystrixCommand(fallbackMethod = “fallback”)

添加:@HystrixCommand(fallbackMethod = “fallback”,commandProperties = {@HystrixProperty(name =“execution.isolation.thread.timeoutInMilliseconds”,value = “1500”) })及fallback方法:

@RestController
@RequestMapping("/order")
@Slf4j
@DefaultProperties(defaultFallback="globalFallback")
public class OrderHystrixController {
    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping(value = "/hystrix/ok/{id}")
    public String paymentInfoOk(@PathVariable("id") Integer id) {
        String result = paymentHystrixService.paymentInfoOk(id);
        log.info("========result:{}========", result);
        return result;
    }

   @HystrixCommand(fallbackMethod = "fallback",commandProperties = {
            @HystrixProperty(name ="execution.isolation.thread.timeoutInMilliseconds",value = "1500")
    })
    @GetMapping(value = "/hystrix/timeout/{id}")
    public String paymentInfoTimeOut(@PathVariable("id") Integer id) {
        String result = paymentHystrixService.paymentInfoTimeOut(id);
        log.info("========result:{}========", result);
        return result;
    }
    public String fallback(Integer id){
        return "太久了我不想等待了,我已经等待了1.5s了!线程池:" + Thread.currentThread().getName() +"访问paymentInfoTimeOut,id=" + id;

    }
}

Feign接口:

@Component
@FeignClient(value = "CLOUD-PAYMENT",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {

    @GetMapping(value = "/payment/hystrix/ok/{id}")
    String paymentInfoOk(@PathVariable("id") Integer id);

    @GetMapping(value = "/payment/hystrix/timeout/{id}")
    String paymentInfoTimeOut(@PathVariable("id") Integer id);
}

客户端测试调用服务端超时降级:

我们发现方法一对一降级,那样代码将越来越多,越来越重复,代码膨胀,所以要设置全局通用服务降级方法。

四、全局通用服务降级

避免代码膨胀,我们设置全局通用服务降级方法,如果需要特殊配置的在另外单独配。

小结:如果注解@HystrixCommand定义fallback方法,走自己定义的fallback方法,反之走全局默认的@DefaultProperties中指定的方法。
总之:全局降级方法的优先级较低,只有业务方法没有指定其降级方法时,服务降级时才会触发全局回退方法。若业务方法指定它自己的回退方法,那么在服务降级时,就只会直接触发它自己的回退方法,而非全局回退方法。

1、类上加注解:DefaultProperties(defaultFallback=" ")指定全局兜底方法

2、方法加注解:@HystrixCommand

3、编写全局降级方法

@RestController
@RequestMapping("/order")
@Slf4j
@DefaultProperties(defaultFallback="globalFallback")
public class OrderHystrixController {
    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping(value = "/hystrix/ok/{id}")
    public String paymentInfoOk(@PathVariable("id") Integer id) {
        String result = paymentHystrixService.paymentInfoOk(id);
        log.info("========result:{}========", result);
        return result;
    }

    @HystrixCommand
    @GetMapping(value = "/hystrix/timeout/{id}")
    public String paymentInfoTimeOut(@PathVariable("id") Integer id) {
        String result = paymentHystrixService.paymentInfoTimeOut(id);
        log.info("========result:{}========", result);
        return result;
    }

    //全局方法降级
    public String globalFallback(){
        return "全局降级!线程池:" + Thread.currentThread().getName() +"访问paymentInfoTimeOut";

    }
}

测试客户端全局降级:

继续思考,所有的降级都在Controller层处理是不是耦合度很高,服务降级每个方法都添加hyxtrix兜底的方法,造成方法的膨胀,既然是服务间的调用,我们能不能将和服务端工程相关的feign接口整体降级,也就是和payment工程相关的都统一降级。

五、解耦服务降级

只需要为Feign客户端定义的接口添加一个服务降级处理的实现类即可实现解耦,也就是@FeignClient注解修饰的这个调用类。

1、新建一个解耦降级处理类

新建一个解耦降级处理类PaymentFallbackService.java,该类实现@FeignClient修饰的PaymentHystrixService接口:

@Component
public class PaymentFallbackService implements PaymentHystrixService {
    @Override
    public String paymentInfoOk(Integer id) {
        return "全局解耦降级处理PaymentFallback->paymentInfoOk!";
    }

    @Override
    public String paymentInfoTimeOut(Integer id) {
        return "全局解耦降级处理PaymentFallback->paymentInfoTimeOut!";
    }
}

2、Feign客户端定义的接口添加fallback

Feign客户端定义的接口PaymentHystrixService.java中添加fallback = PaymentFallbackService.class

@Component
@FeignClient(value = "CLOUD-PAYMENT",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {

    @GetMapping(value = "/payment/hystrix/ok/{id}")
    String paymentInfoOk(@PathVariable("id") Integer id);

    @GetMapping(value = "/payment/hystrix/timeout/{id}")
    String paymentInfoTimeOut(@PathVariable("id") Integer id);
}

3、测试降级

Tip:如果不生效,检查该实现类是否以组件的形式添加 Spring 容器中,最常用的方式就是在类上标注 @Service注解或者@Component注解。

在这里插入图片描述

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

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

相关文章

三翼鸟:传统品牌只盯局部,智慧品牌谋划全局

“当今企业之间的竞争&#xff0c;不是产品之间的竞争&#xff0c;而是商业模式之间的竞争。”很多人都听过现代管理学之父德鲁克的这句话&#xff0c;但又有多少人真正理解了它&#xff1f; 以当下的语境去看&#xff0c;这里其实就是“自利”和“共荣”的区别。前者&#xf…

多臂老虎机问题

1.问题简介 多臂老虎机问题可以被看作简化版的强化学习问题&#xff0c;算是最简单的“和环境交互中的学习”的一种形式&#xff0c;不存在状态信息&#xff0c;只有动作和奖励。多臂老虎机中的探索与利用&#xff08;exploration vs. exploitation&#xff09;问题一直以来都…

Zabbix“专家坐诊”第189期问答汇总

问题一 Q&#xff1a;您好&#xff0c;为什么在shell脚本中&#xff0c;不写mysql命令的绝对路径&#xff0c;zabbix获取不到输出的值&#xff1f; A&#xff1a;mysql默认命令是针对root等有权限才能直接使用的&#xff0c;其他用户要使用要指定命令路径。 Q&#xff1a;zab…

SLB负载均衡haproxy的安装及使用

1.介绍 HAProxy是什么 HAProxy是一个免费的负载均衡软件&#xff0c;可以运行于大部分主流的Linux操作系统上。 HAProxy提供了L4(TCP)和L7(HTTP)两种负载均衡能力&#xff0c;具备丰富的功能。HAProxy的社区非常活跃&#xff0c;版本更新快速&#xff08;最新稳定版1.7.2于2…

【剧前爆米花--爪哇岛寻宝】网络互连,网络通信和网络分层

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaEE初阶》 文章分布&#xff1a;这是一篇关于网络初识的文章&#xff0c;在这篇文章中讲解了局域网广域网&#xff0c;IP地址&#xff0c;端口以及网络分层等相关内容&#xff0c;希望对你有所帮助&#xff01; 目录 网络互连…

无线通信网 - 无线局域网 WLAN(802.11 标准)

文章目录 1 概述2 WLAN2.1 802.11 标准2.2 网络分类2.3 通信技术 3 扩展3.1 移动通信3.2 网工软考真题 1 概述 #mermaid-svg-UcgosJsdJfSTEm0Y {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-UcgosJsdJfSTEm0Y .err…

PMO和PM必备六大复盘方法工具汇总

无论是对于企业还是个人来说&#xff0c;复盘都是一个能让我们快速成长的方法&#xff0c;尤其是项目经理和PMO&#xff0c;你是带领项目团队的&#xff0c;每一次项目的完成&#xff0c;都有很多经验&#xff0c;俗话说&#xff0c;最大的浪费是经验的浪费&#xff01; 复盘的…

如何解决国外主机托管中遇到的常见问题?

在国际化发展的今天&#xff0c;越来越多的企业和个人选择将网站托管在国外主机上。这样做的好处是显而易见的&#xff0c;如更好的网站访问速度、更多的服务器资源、更优质的服务和更灵活的管理权限等。但同时&#xff0c;使用国外主机也会带来一些问题。本文将讨论国外主机托…

浪潮信息龙蜥联合实验室领衔成立 Serverless SIG 打造标准化开源解决方案

近日&#xff0c;浪潮信息龙蜥联合实验室在龙蜥社区领衔成立 Serverless SIG&#xff08;服务器无感知计算 SIG&#xff09;&#xff0c;并举行了首届 Serverless SIG MeetUp&#xff0c;活动由浪潮信息龙蜥联合实验室主办&#xff0c;来自浪潮信息、天津大学、阿里云、Intel、…

面板数据熵权topsis法分析流程

面板数据熵权topsis法分析流程 一、案例背景 当前有9家公司连续5年&#xff08;2018-2022年&#xff09;的财务指标数据&#xff0c;想要通过这份数据&#xff0c;确定9家公司的财务排名情况。因为各项财务指标的权重有所不同&#xff0c;所以选择使用熵权topsis法进行研究。 …

unity GI 系统

间接光没有办法实现实时计算&#xff0c;所以需要一套GI系统去处理间接光。 GI系统主要解决的是间接光漫反射的实现&#xff0c;实现的载体是LightMap、Light Probe、Refletion Probe。需要一个后台程序&#xff08;离线渲染器&#xff09;来实现离线渲染。可以根据不同的物体…

iPhone清理工具:4Easysoft iPhone Cleaner for Mac

4Easysoft iPhone Cleaner for Mac是一款Mac上的iPhone清理软件&#xff0c;它可以帮助用户清理iPhone上的垃圾文件、缓存文件、无用图片和视频等&#xff0c;从而释放iPhone的存储空间&#xff0c;提高设备的性能。全面扫描您的 iOS 设备并对不必要的数据进行分类。轻松删除 i…

【软件测试面试】面试技巧,让面试官记住的自我介绍,疯狂收割offer.....

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 在讨论如何自我介…

CASAIM全自动3d测量仪自动检测差速器差壳全尺寸测量装配检测

随着汽车行业的新变化&#xff0c;汽车零部件行业也呈现出新的发展趋势。汽车零部件产品作为汽车制造业的配套产业&#xff0c;发展也十分迅速。  差速器作为汽车关键零部件&#xff0c;由差速器差壳、行星齿轮、半轴齿轮、半轴和行星齿轮轴组装而成。 差速器差壳通常采用一…

算法基础(三)(共有20道例题)

七、数学知识 &#xff08;一&#xff09;质数 质数&#xff08;素数&#xff09; 的定义&#xff1a; 互质的定义&#xff1a;除了1以外&#xff0c;两个没有其他共同质因子的正整数称为互质&#xff0c;比如3和7互质。因为1没有质因子&#xff0c;1与任何正整数&#xff08…

ASEMI代理ADI亚德诺ADM202EARNZ-REEL车规级芯片

编辑-Z ADM202EARNZ-REEL芯片参数&#xff1a; 型号&#xff1a;ADM202EARNZ-REEL 工作电压范围&#xff1a;4.5-5.5V VCC电源电流&#xff1a;2.5 mA 输入逻辑阈值低&#xff1a;0.8V 输入逻辑阈值高&#xff1a;2.4V 输出电压摆幅&#xff1a;9.0V 变送器输出电阻&am…

IMF: Interactive Multimodal Fusion Model for Link Prediction

[2303.10816] IMF: Interactive Multimodal Fusion Model for Link Prediction (arxiv.org) 目录 1 背景 2 贡献 3 模型 3.1 Overall Architecture 3.2 Modality-Specific Encoders 3.3 Multimodal Fusion 3.4 Contextual Relational Model 3.5 Decision Fusion 3.6 …

GNSS监测站在滑坡和地质灾害中的应用

《地质灾害防治条例》涉及的地质灾害包括崩塌、滑坡、泥石流、地面沉降、地面塌陷和地裂缝等&#xff0c;已成为我国主要的自然灾害&#xff0c;严重威胁着人民的生命财产安全和生存环境以及国家重大工程的建设&#xff0c;制约着我国国民经济的可持续发展。 我国的地质灾害监…

【gcd性质】最小公倍数挑战

题目-最小公倍数挑战 (51nod.com) 题意&#xff1a; 思路&#xff1a; 要找到三个数使得他们的lcm尽可能大 那就让这三个数都两两互质&#xff0c;且三个数的积尽可能大 若n为奇数&#xff0c;考虑n-1和n-2 n和n-1一定互质&#xff0c;那么考虑n和n-2是否互质 结论是&…

【计算机基本原理-数据结构】数据结构中树的详解

【计算机基本原理-数据结构】数据结构中树的详解 1&#xff09;总览2&#xff09;树的相关概念3&#xff09;二叉树、满二叉树、完全二叉树4&#xff09;二叉查找树 - BST5&#xff09;平衡二叉树 - AVL6&#xff09;红黑树7&#xff09;哈弗曼树8&#xff09;B 树9&#xff09…