Hystrix 断路器

news2024/10/6 14:32:05

文章目录

      • 1 问题:服务雪崩
      • 2 概念
      • 3 服务降级
        • 3.1 概念:
        • 3.2 触发服务降级的情况:
        • 3.3 应用
          • 3.3.1 依赖
          • 3.3.2 解决的问题
          • 3.3.3 生产者:
          • 3.3.4 消费者:
          • 3.3.5 配置全局fallback方法
          • 3.3.6 解耦合
      • 4 服务熔断
        • 4.1 概念:
        • 4.2 注解
        • 4.3 应用
        • 4.4 原来的主逻辑要如何恢复呢?
      • 5 服务限流
        • 5.1 概念:
      • 6 服务监控 hystrixDashboard
        • 6.1 依赖
        • 6.2 主启动类添加注解@EnableHystrixDashboard
        • 6.3 访问图形化界面
        • 6.4 调整需要监控的服务主启动类
        • 6.5 输入监控的url

想要学习完整SpringCloud架构可跳转: SpringCloud Alibaba微服务分布式架构

1 问题:服务雪崩

多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的**“扇出"**。

如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”。

对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。

比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。

这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。

所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或

者叫雪崩。

2 概念

Hystrix是一个用于处理分布式系统的延迟容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等Hystrix能够保证在一个依赖出

问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

"断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应

(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布

式系统中的蔓延,乃至雪崩。

3 服务降级

3.1 概念:

服务不可用了,不让客户端等待,并立刻返回一个友好提示,fallback。

3.2 触发服务降级的情况:

  • 程序运行异常
  • 超时
  • 服务熔断触发服务降级
  • 线程池/信号量打满

3.3 应用

3.3.1 依赖
        <!-- hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
3.3.2 解决的问题

超时导致服务器变慢(转圈)-》超时不再等待-》服务降级

出错(宕机或程序运行出错)-》出错要有兜底-》服务降级

生产者正常,消费者自己出现故障或有自我要求(自己的等待时间小于服务提供者响应时间)

3.3.3 生产者:

设置自身调用后超时时间的峰值,超过峰值做服务降级fallback

一旦调用服务方法失败并抛出错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法

系统运行报错也会走fallbackMethod标注的方法。

    /**
     * 超时
     *
     * @param id
     * @return
     */
    //@HystrixCommand 服务降级规则 响应超过3000毫秒,则执行paymentInfo_TimeOutHandler方法
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    @Override
    public String paymentInfo_TimeOut(Integer id) {
        int timeNumber = 5;
        try {
            TimeUnit.SECONDS.sleep(timeNumber);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + " paymentInfo_OK,id: " + id + "\t" + "O(∩_∩)O哈哈~" + ",耗时" + timeNumber + "秒钟";
    }

    public String paymentInfo_TimeOutHandler(Integer id) {
        return "o(╥﹏╥)o\r\n调用支付接口超时或异常:\t" + "\t当前线程池名称" + Thread.currentThread().getName();
    }

主启动类添加@EnableCircuitBreaker注解

@EnableCircuitBreaker
@EnableEurekaClient
@SpringBootApplication
public class PaymentHystrixMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrixMain8001.class,args);
    }
}
3.3.4 消费者:

配置文件中开启 feign 对 hystrix 的支持

feign:
  hystrix:
    # 开启 feign 对 hystrix 的支持
    enabled: true

主启动类添加@EnableHystrix注解

@EnableHystrix
@EnableFeignClients
@SpringBootApplication
public class OrderHystrixMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderHystrixMain80.class,args);
    }
}

HystrixCommand:

    @GetMapping("/hystrix/TimeOut/{id}")
    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    })
    @ApiOperation(value = "超时接口", response = String.class)
    public String paymentInfo_TimeOut(@PathVariable("id")Integer id){
        String result = paymentHystrixService.paymentInfo_TimeOut(id);
        return result;
    }

    public String paymentTimeOutFallbackMethod(Integer id) {
        return "我是消费者80,对方支付系统繁忙,请10秒后重试\r\no(╥﹏╥)o";
    }

需要设置熔断器超时峰值,否则会报错

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            # 设置熔断器超时峰值
            timeoutInMilliseconds: 5000
3.3.5 配置全局fallback方法
@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
@RequestMapping("consumer")
@Api(tags = {"整合Hystrix订单系统控制层"})
public class OrderHystirxController {

    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping("/hystrix/OK/{id}")
    @HystrixCommand
    @ApiOperation(value = "正常接口", response = String.class)
    public String paymentInfo_OK(@PathVariable("id") Integer id){
        String result = paymentHystrixService.paymentInfo_OK(id);
        return result;
    }

    /**
     * 全局fallback方法
     * @return
     */
    public String payment_Global_FallbackMethod(){
        return "payment系统繁忙,请联系客服处理\n" +
                "o(╥﹏╥)o";
    }

}

如果配置了@HystrixCommand中的fallbackMethod属性,则走专属配置的,没有则走全局的。

3.3.6 解耦合
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {

    @GetMapping("/payment/hystrix/OK/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id);

    @GetMapping("/payment/hystrix/TimeOut/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id")Integer id);

}
@Component
public class PaymentFallbackService implements PaymentHystrixService {

    @Override
    public String paymentInfo_OK(Integer id) {
        return "-----PaymentFallbackService fall back-paymentInfo_OK\r\no(╥﹏╥)o";
    }

    @Override
    public String paymentInfo_TimeOut(Integer id) {
        return "-----PaymentFallbackService fall back-paymentInfo_TimeOut\r\no(╥﹏╥)o";
    }

}

4 服务熔断

4.1 概念:

类似于保险丝达到最大服务访问量后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示。

熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。

当检测到该节点微服务调用响应正常后,恢复调用链路。

在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,

当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand。

4.2 注解

    //=====服务熔断=====
    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),//是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),//时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")//失败率达到多少后跳闸
    })
    @Override
    public String paymentCircuitBreaker(@PathVariable("id") Integer id) {

涉及到断路器的三个重要参数:快照时间窗、请求总数阀值、错误百分比阀值。

1: 快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒。

2∶请求总数阀值:在快照时间窗内,必须满足请求总数阀值才有资格熔断。默认为20,意味着在10秒内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。

3∶错误百分比阀值:当请求总数在快照时间窗内超过了阀值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过
50%的错误百分比,在默认设定50%阀值情况下,这时候就会将断路器打开。

4.3 应用

@Service
public class PaymentServiceImpl implements PaymentService {

    //=====服务熔断=====
    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),//是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),//时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")//失败率达到多少后跳闸
    })
    @Override
    public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
        if (id < 0) {
            throw new RuntimeException("******id不能负数");
        }
        String serialNumber = IdUtil.simpleUUID();
        return Thread.currentThread().getName() + "\t" + "调用成功,流水号: " + serialNumber;
    }

    public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id) {
        return "id不能负数,请稍后再试,/(ToT)/~~id: " + id;
    }


}
@RestController
@Slf4j
@RequestMapping("/payment")
@Api(tags = {"整合hystrix支付系统控制层"})
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    //=====服务熔断=====
    @GetMapping("/hystrix/circuit/{id}")
    @ApiOperation(value = "服务熔断接口", response = String.class)
    public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
        String result = paymentService.paymentCircuitBreaker(id);
        log.info("result:" + result);
        return result;
    }

}

4.4 原来的主逻辑要如何恢复呢?

对于这一问题,hystrix也为我们实现了自动恢复功能。

当断路器打开,对主逻辑进行熔断之后,hystrix会启动一个休眠时间窗,在这个时间窗内,降级逻辑是临时的成为主逻辑,当休眠时间窗到期,断路器将进入半开状态,释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器将继续闭合,主逻辑恢复,如果这次请求依然有问题,断路器继续进入打开状态,休眠时间窗重新计时。

5 服务限流

5.1 概念:

秒杀、高并发等操作,严禁其一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行。

6 服务监控 hystrixDashboard

除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。

Netfiix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。

6.1 依赖

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

6.2 主启动类添加注解@EnableHystrixDashboard

@SpringBootApplication
@EnableHystrixDashboard//开启图形化监控界面
public class HystrixDashboardMain9001 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixDashboardMain9001.class,args);
    }
}

6.3 访问图形化界面

http://localhost:9001/hystrix

6.4 调整需要监控的服务主启动类

@EnableCircuitBreaker//开启熔断器
@EnableEurekaClient
@SpringBootApplication
public class PaymentHystrixMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrixMain8001.class, args);
    }
    /**
     * 此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的玩
     * ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",
     * 只要在自己的项目里配置上下面的servlet就可以了
     */
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

6.5 输入监控的url

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

Shell的条件运算语句

目录 IF语句 单分支语句语法语法 多分支结构语法 CASE语句 语法 IF语句 单分支语句语法语法 #写法1 if 条件语句 then内容 fi#写法2 if 条件语句 ;then内容 fi编写一个内容警报器的例子 #!/bin/bash free_mem$(free -m | grep "Mem:" | tr -s " "…

kubernetes源码学习之kube-scheduler

kube-scheduler是kubernetes中的调度程序&#xff0c;负责从api server中获得待分发的pod列表&#xff0c;并为他们找到最合适运行的Node。 基于kubernetes 1.27 基本框架 下面是kubernetes官发给出的框架图&#xff0c;先对kubernetes pod调度的大致流程有一个认识 看一下有…

眼睛:来一场视觉盛宴《手拿把掐》css特效 —— 之听说过CSS【笑】

&#x1f637;&#x1f60a;&#x1f93a;&#x1f93a;&#x1f93a;前期回顾 打造极简风格动效 —— 5 分钟轻松实现惊艳、震撼人心的视觉效果_彩色之外的博客-CSDN博客 &#x1f601; css动画 —— 把你喜欢css动画嵌入到浏览器中_css做的动画效果怎么嵌入网页_彩色之外的…

window电脑修复网络不能正常

问题描述 问题的起点是我打开了OpenAPI公司的GPT&#xff0c;在回答的过程中响应很慢&#xff0c;然后自己开始尝试切换连接的服务器&#xff08;这里使用到了网络代理&#xff09;&#xff0c;最后自己做了一个操作是 代理软件的这个菜单里面的增强模式选项&#xff0c;结果…

Android爬坑指南————工信部又出新规!

工信部又出新规了&#xff01; 一、背景二、整改2.1 个人信息保护2.1.1 基本模式&#xff08;无权限、无个人信息获取模式&#xff09;腾讯视频网易云音乐 2.1.2 隐私政策内容 2.2 app权限调用2.2.1 应用内权限调用2.2.1.1 获取定位信息和生物特征识别信息2.2.1.2 其他权限 2.3…

渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的?

在上一篇文章中我们介绍了导航相关的流程&#xff0c;那导航被提交后又会怎么样呢&#xff1f; 就进入了渲染阶段。这个阶段很重要&#xff0c;了解其相关流程能让你“看透”页面是如何工作的&#xff0c;有了这些知识&#xff0c;你可以解决一系列相关的问题&#xff0c;比如…

SVR算法简介及与其它回归算法的关系

目录 参考链接 有人可以帮助我理解支持向量回归技术和其他简单回归模型之间的主要区别是什么 支持向量回归找到一个线性函数&#xff0c;表示误差范围 (epsilon) 内的数据。也就是说&#xff0c;大多数点都可以在该边距内找到&#xff0c;如下图所示 这意味着 SVR 比大多数其…

TypeScript 学习笔记(一):基本类型、交叉类型、联合类型、类型断言

文章目录 一、常见类型1. 数组2. 布尔3. 数值4. 字符串5. object6. null 和 undefined7. symbol7.1 作为属性名7.2 属性名遍历7.3 静态方法&#xff1a;Symbol.for()和 Symbol.keyFor()7.4 内置 symbol 值7.4.1 Symbol.hasInstance7.4.2 Symbol.isConcatSpreadable7.4.3 Symbol…

Android 报错,闪退(错误)日志保存到手机内存中,以文本文件的形式保存

1.直接贴代码 import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Environment; import android.util.Log;import com.nuotu.atmBookClient.App;import java.io.File; i…

python接口自动化(三十二)--Python发送邮件(常见四种邮件内容)番外篇——上(详解)

简介 本篇文章与前边没有多大关联&#xff0c;就是对前边有关发邮件的总结和梳理。在写脚本时&#xff0c;放到后台运行&#xff0c;想知道执行情况&#xff0c;会通过邮件、SMS&#xff08;短信&#xff09;、飞信、微信等方式通知管理员&#xff0c;用的最多的是邮件。在linu…

这份4577页的Java面试PDF,让我成功斩获阿里、字节等大厂offer

我为大家准备了一份超级全面的Java 学习面试笔记&#xff0c;这份电子版笔记涵盖了诸多后端技术栈的面试题和答案&#xff0c;相信可以帮助大家在最短的时间内复习Java后端的大多数技术点和面试题&#xff0c;从而拿到自己心仪的offer。共4577页。整体还是比较清爽的&#xff0…

Postman的细节回顾

之前在学校摸索着玩过postman&#xff0c;工作后要使用postman&#xff0c;发现对于很多细节&#xff0c;这里补充说明一下&#xff0c;当作使用手册。 之所以使用postman&#xff0c;是因为更便捷的查看接口情况&#xff0c;不需要每次在浏览器f12查看。 目录 1 创建请求2 测…

产品经理怎么管理项目进度?

作为在职七年的项目管理人员&#xff0c;在项目进度管理上确实有一点发言权。产品经理作为企业的核心骨干岗位之一&#xff0c;在进行项目进度管理时也会有很多问题出现&#xff0c;那么应该怎样去管理项目进度呢&#xff1f;以下是答主的一些拙见&#xff0c;有需要的朋友们就…

C. Particles

Problem - C - Codeforces 思路&#xff1a;通过题意能够知道如果移除i&#xff0c;那么i-1与i1会合成一个新的&#xff0c;同时后面的往前移动两个单位&#xff0c;并且我们发现可以让1 3 5 7 ... 2*n-1合成一个数&#xff0c;让2 4 6 8 ... 2*n合成一个数&#xff0c;同时我们…

java自我学习记录day02

java日常学习 1.继承2.super3.方法重写/覆盖4.多态5.Object类和equals的对比equals用于判断值是否相等hashCode方法toString方法finalize方法 6.刷题&#xff08;03&#xff09;题三&#xff1a;在排序数组中查找元素的第一个和最后一个位置 1.继承 如果希望指定去调用父类的某…

uniapp 小程序 filters 过滤日期

页面效果&#xff1a; <template><view class"order-intro-item"><text class"left-label">日期</text><text class"right-info time-text">{{startClearingTime | formatData}} 至 {{endClearingTime | format…

21. 斐波那契数列

链接&#xff1a; 链接 题目&#xff1a; 输入一个整数 nn &#xff0c;求斐波那契数列的第 nn 项。 假定从 00 开始&#xff0c;第 00 项为 00。 数据范围 0≤n≤390≤n≤39 样例 输入整数 n5 返回 5 思路&#xff1a; 0返回0&#xff0c;1&#xff0c;2都返回1&#xff0c;后…

数据库备份恢复和索引视图

样例表如下&#xff1a; /***************************样例表***************************/CREATE DATABASE booksDB;use booksDB;CREATE TABLE books(bk_id INT NOT NULL PRIMARY KEY,bk_title VARCHAR(50) NOT NULL,copyright YEAR NOT NULL);INSERT INTO booksVALUES (1107…

IPv6 over IPv4 之SIT隧道

一.SIT模块功能简介 SIT模块是支持ISATAP隧道和6to4隧道两种隧道模式的 ISATAP和6to4都是目前比较流行的自动建立隧道的过渡技术&#xff0c;都可以连接被IPv4隔绝的IPv6孤岛&#xff0c;都是通过将IPv4地址嵌入到IPv6地址当中&#xff0c;并将IPv6封包封装在IPv4中传送&…

第一章介绍处理器(Cortex-M7 Processor)

目录 第一章引言本章介绍处理器。 1.1关于Cortex-M7处理器 1.1.1特性 1.1.2接口 1.1.3配置选项 1.2组件模块 1.2.1数据处理单元 1.2.2预取单元 1.2.3负载存储单元 1.2.4浮点单元 1.2.5嵌套矢量中断控制器 1.2.6唤醒中断控制器 1.2.7记忆系统 1.2.8存储缓冲区 1.2.9内…