服务熔断保护实践--Hystrix

概述

微服务有很多互相调用的服务,构成一系列的调用链路,如果调用链路中某个服务失效或者网络堵塞等问题,而有较多请求都需要调用有问题的服务时,这是就会造成多个服务的大面积失效,造成服务“雪崩”效应。

服务“雪崩”的根本原因在于服务之间的强依赖,为了预防服务“雪崩”这一问题,可以做好服务隔离、服务熔断降级、服务限流。

服务隔离:当某个服务故障时,不波及其他模块,不影响整体服务。

服务熔断:当下游服务因为请求压力过大造成响应慢或响应失败时,上游服务为了保护系统,暂时切断对下游服务的调用,直接返回一个降级的内容,从而保全整体系统。

服务限流:限制系统的输入和输出达到保护系统的目的,例如:限制请求速率,超出的请求不处理或者暂缓处理或降级处理。

本文介绍的服务熔断组件是Hystrix。

本文的操作是在 微服务负载均衡实践 的基础上进行。

环境说明

jdk1.8

maven3.6.3

mysql8

spring cloud2021.0.8

spring boot2.7.12

idea2022

步骤

在请求的接口类使用hystrix的服务熔断
1.添加依赖

在order-service里添加依赖

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

在spring cloud 的2021.0.8版本里,找不到netflix-hystrix了,引入依赖需要单独添加版本号

2.激活hystrix

在order-service启动类上方添加注解@EnableHystrix注解

@EnableHystrix
public class OrderApplication {

3.降级处理

修改OrderController类

(1)在OrderController添加降级方法

/**
 * 降级方法
 *  和需要受到保护的方法的 返回值一致、方法参数一致
 */
public Product orderFallBack(Long id){
    Product product = new Product();
    product.setProductName("触发降级方法");
    return product;
}

(2)在需要受到保护的方法上使用@HystrixCommand配置

/**
 * 使用注解配置熔断保护
 *   fallbackmethod:配置熔断之后的降级方法
 */
@HystrixCommand(fallbackMethod = "orderFallBack")
@RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)
public Product findById(@PathVariable Long id){

4.模拟网络延迟

在product-service的服务方法,添加2秒睡眠时间

		try {
            Thread.sleep(2000l);//模拟网络延迟
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

5.Hystrix配置

order-service的application.yml中添加如下配置

hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: ExecutionIsolationStrategy.SEMAPHORE #信号量隔离
          #strategy: # ExecutionIsolationStrategy.THREAD 线程池隔离
          thread:
            timeoutInMilliseconds: 2000 #默认的连接超时时间1秒,若1秒没有返回数据,自动的触发降级逻辑
      circuitBreaker:
        requestVolumeThreshold: 5 #触发熔断的最小请求次数,默认20 /10秒
        sleepWindowInMilliseconds: 10000 #熔断多少秒后去尝试请求 默认 5   打开状态的时间
        errorThresholdPercentage: 50 #触发熔断的失败请求最小占比,默认50%

6.测试

启动eureka、product、order服务

浏览器访问

http://localhost:9002/order/buy/1

因为product服务方法里模拟请求网络延迟,设置有2s的睡眠时间,加上到数据库请求数据的一些耗时过程,总的请求时间将大于2s,而线程超时时间设置为2s,所以会触发降级方法。

把线程超时时间调大,例如:调整为6秒

重新启动order-service,浏览访问测试,能正常访问到数据。

7.统一的降级方法

如果每个方法都写一个降级方法,方法多的时候,很麻烦,可以统一指定降级方法。

修改OrderController类,添加统一降级方法

	/**
     * 指定统一的降级方法
     *   注意方法没有参数
     */
    public Product defaultFallBack(){
        Product product = new Product();
        product.setProductName("触发统一的降级方法");
        return product;
    }

在OrderController类上方添加@DefaultProperties注解

@DefaultProperties(defaultFallback = "defaultFallBack")
public class OrderController {

修改findById方法上方的@HystrixCommand注解,将
@HystrixCommand(fallbackMethod = "orderFallBack")
改为
@HystrixCommand

修改order-service的application.yml配置,将线程超时时间改为2000

重启order服务

测试

触发了统一的降级方法,说明统一的服务降级方法生效。

Feign结合hystrix的服务熔断
1.复制服务

复制order-service得到order-service-feign_hystrix(注意:在idea里直接复制会有问题。在文件资源管理器里复制才不会出现问题。

修改order-service-feign_hystrix的pom.xml,修改artifactId为如下

<artifactId>order-service-feign_hystrix</artifactId>

在父工程pom.xml添加一个模块

<module>order-service-feign_hystrix</module>

在order-service-feign_hystrix服务操作

2.feign中开启hystrix及相关配置

修改order-service-feign_hystrix服务application.yml在Fegin中开启hystrix

# 在feign中开启hystrix熔断
feign:
  circuitbreaker:
    enabled: true

修改 端口号及服务名称

server:
  port: 9003
spring:
  application:
    name: service-order-feign_hustrix

hystrix设置

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 2000 #默认的连接超时时间1秒,若1秒没有返回数据,自动的触发降级逻辑
      circuitBreaker:
        enabled: true
        requestVolumeThreshold: 5
        errorThresholdPercentage: 10
        sleepWindowInMilliseconds: 10000
3.接口实现类中实现降级逻辑

编写接口实现类,编写熔断降级方法

package org.example.order.feign;

import org.example.order.entity.Product;
import org.springframework.stereotype.Component;

@Component
public class ProductFeginClientCallBack implements ProductFeignClient{
    /**
     * 降级方法
     */
    @Override
    public Product findById(Long id) {
        Product product = new Product();
        product.setProductName("触发Feign熔断降级方法");
        return product;
    }
}
4.接口注解申明降级类

修改ProductFeignClient接口类

@FeignClient添加使用降级的方法所在的类 fallback = ProductFeginClientCallBack.class

@FeignClient(name = "service-product", fallback = ProductFeginClientCallBack.class)
public interface ProductFeignClient {

    /**
     * 配置需要调用的微服务接口
     * @return
     */
    @RequestMapping(value = "/product/{id}", method = RequestMethod.GET)
    Product findById(@PathVariable("id") Long id);
}
5.注释或删除之前的Hystrix相关代码

注释或删除启动类的@EnableHystrix注解

//@EnableHystrix
public class OrderApplication {

注释或删除OrderController之前的Hystrix相关的内容

6.启动及测试

启动eureka、product、order(9003)服务

浏览器访问

http://localhost:9003/order/buy/1

请求响应时间超过线程时间限制,触发了Feign熔断降级方法。

修改order的application.yml配置文件,设置线程超时时间为6000毫秒

重启order(9003)服务

浏览器访问

返回时间小于设置的超时时间,不触发降级方法,返回正常数据。

Feign实现服务熔断总结:

1.配置添加开启服务熔断,并设置hystrix超时参数

2.添加ProductFeignClient接口的实现类,在实现类里实现降级逻辑。

3.在ProductFeignClient接口类中的注解声明降级类

hystrix监控

如何才能了解断路器中的状态呢?hystrix监控可以做到这一点。

在order-service操作

1.导入依赖
        <!--监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>

2.启用HystrixDashboard监控

在启动类上方添加@EnableHystrixDashboard注解

@EnableHystrixDashboard
public class OrderApplication {

3.启动服务

启动eureka、product、order服务

4.初步测试

浏览器访问

http://localhost:9002/hystrix

http://localhost:9002/actuator

返回的数据格式化后,如下:

{
	"_links": {
		"self": {
			"href": "http://localhost:9002/actuator",
			"templated": false
		},
		"health": {
			"href": "http://localhost:9002/actuator/health",
			"templated": false
		},
		"health-path": {
			"href": "http://localhost:9002/actuator/health/{*path}",
			"templated": true
		}
	}
}

6.修改配置

修改order服务的application.yml

给actuator暴露端点

# 给actuator暴露端点
management:
  endpoints:
    web:
      exposure:
        include: "*"

注意:隔离设置为线程池隔离

hystrix:
  command:
    default:
      execution:
        isolation:
#          strategy: SEMAPHORE #信号量隔离
          strategy: THREAD #线程池隔离

 配置允许的主机

hystrix:
  dashboard:
    proxy-stream-allow-list: localhost
7.测试

重启order服务

浏览器访问

http://localhost:9002/actuator/hystrix.stream

正常可以看到持续输出ping: 

浏览器访问

http://localhost:9002/hystrix

在Hystrix Dashboard页面输入框中,填写

http://localhost:9002/actuator/hystrix.stream

点击Monitor Stream

此时Circuit和Threads Pools都是loading状态,还没有具体数据

访问一次9002的服务

http://localhost:9002/order/buy/1

查看hystrix的dashboard,有数据了。

 

访问多次

http://localhost:9002/order/buy/1

看到监控页面,有折线图,表示触发熔断的情况

各指标的含义

断路器的三种状态:Closed、Open、Half Open

Closed(关闭):

    所有请求都可以正常访问

Open(开启)

    所有请求都会进入降级方法中

Half Open(半开)

    维持Open状态一段时间(5s)后,断路器进入半开状态,尝试释放一个请求到远程微服务,如果服务访问正常,断路器就进入Closed状态,如果不能访问,继续保存Open状态5s。

完成!enjoy it!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

十九、类型信息(2)

本章概要 Class 对象 类字面常量泛化的 Class 引用cast() 方法 Class 对象 要理解 RTTI 在 Java 中的工作原理&#xff0c;首先必须知道类型信息在运行时是如何表示的。这项工作是由称为 **Class**对象 的特殊对象完成的&#xff0c;它包含了与类有关的信息。实际上&#x…

JVM第二十三讲:Java动态调试技术原理

Java动态调试技术原理 本文是JVM第二十三讲&#xff0c;Java动态调试技术原理。转载自 美团技术团队胡健的Java 动态调试技术原理及实践&#xff0c;通过学习java agent方式进行动态调试&#xff0c;了解目前很多大厂开源的一些基于此的调试工具 (例如来自阿里开源的Arthas)。 …

微信小程序设计之主体文件app-wxss/less

一、新建一个项目 首先&#xff0c;下载微信小程序开发工具&#xff0c;具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后&#xff0c;注册小程序账号&#xff0c;具体注册方法&#xff0c;可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…

elementUI 特定分辨率(如1920*1080)下el-row未超出一行却换行

在1920*1080分辨率下&#xff0c; el-col 内容未超出 el-col 宽度&#xff0c;el-col 不足以占据一行&#xff0c;el-row 却自动换行了&#xff08;其他分辨率没有这个问题&#xff09;。 截图&#xff1a; 排查&#xff1a; el-col 内容没有溢出&#xff1b;没有多余的 pad…

拜耳阵列(Bayer Pattern)和解马赛克简介

拜尔阵列 典型的图像传感器&#xff08;例如我们在数码相机中使用的图像传感器&#xff0c;主要有CCD, CMOS&#xff09;由许多单独的光电传感器组成&#xff0c;所有这些传感器都会捕获光线。这些光电传感器本身能够捕获光的强度&#xff0c;但不能捕获其波长&#xff08;颜色…

CTF-Web(3)文件上传漏洞

笔记目录 CTF-Web(2)SQL注入CTF-Web(3)文件上传漏洞 1.WebShell介绍 (1)一句话木马定义 一种网页后门&#xff0c;以asp、php、jsp等网页文件形式存在的一种命令执行环境&#xff0c;而 一句话木马往往只有一行WebShell代码。 作用&#xff1a; 攻击获得网站控制权限 查看、修改…

如何防范AI等技术带来的诈骗风险?从技术、法律、教育等多方面入手

文章目录 前言什么是AI诈骗案例案例一案例二 AI诈骗的特点如何预防和应对AI诈骗建议后记 前言 互联网是一把双刃剑&#xff0c;这是我们常说的一个问题。 随着人工智能技术的快速发展&#xff0c;AI诈骗成为当今社会面临的新兴威胁。不法分子利用人工智能技术&#xff0c;以更…

Qt之实现支持多选的QCombobox

一.效果 1.点击下拉列表的复选框区域 2.点击下拉列表的非复选框区域 二.实现 QHCustomComboBox.h #ifndef QHCUSTOMCOMBOBOX_H #define QHCUSTOMCOMBOBOX_H#include <QLineEdit> #include <QListWidget> #include <QCheckBox> #include <QComboBox>…

面试算法43:在完全二叉树中添加节点

题目 在完全二叉树中&#xff0c;除最后一层之外其他层的节点都是满的&#xff08;第n层有2n-1个节点&#xff09;。最后一层的节点可能不满&#xff0c;该层所有的节点尽可能向左边靠拢。例如&#xff0c;图7.3中的4棵二叉树均为完全二叉树。实现数据结构CBTInserter有如下3种…

Vue 3 响应式对象:ref 和 reactive 的使用和区别

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是尘缘&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f449;点击这里&#xff0c;就可以查看我的主页啦&#xff01;&#x1f447;&#x…

Flink CDC 2.0 主要是借鉴 DBLog 算法

DBLog 算法原理 DBLog 这个算法的原理分成两个部分&#xff0c;第一部分是分 chunk&#xff0c;第二部分是读 chunk。分 chunk 就是把一张表分为多个 chunk&#xff08;桶/片&#xff09;。我可以把这些 chunk 分发给不同的并发的 task 去做。例如&#xff1a;有 reader1 和 re…

二叉树的最近公共祖先

题目&#xff1a; 样例&#xff1a; 输入 6 1 4 2 5 -1 -1 1 4 -1 -1 -1 -1 -1 3 输出 2 思路&#xff1a; 由题意&#xff0c;最近公共祖先就是&#xff0c;找出给出的两个结点的父结点 是谁。 这里有两种情况 1、给定的两个结点都是孩子结点 2、给定的两个结点&#xff…

【送书福利-第二十二期】《Vue.js 3企业级项目开发实战(微课视频版)》

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

Table-GPT:让大语言模型理解表格数据

llm对文本指令非常有用&#xff0c;但是如果我们尝试向模型提供某种文本格式的表格数据和该表格上的问题&#xff0c;LLM更有可能产生不准确的响应。 在这篇文章中&#xff0c;我们将介绍微软发表的一篇研究论文&#xff0c;“Table-GPT: Table- tuning GPT for Diverse Table…

用示例和应用程序了解必要的Golang库

Golang&#xff0c;也被称为Go&#xff0c;因其简单性、性能和并发性支持而在开发人员中迅速流行起来。导致Go成功的关键因素之一是其丰富的库生态系统&#xff0c;可以简化开发并提供解决常见问题的解决方案。在本文中&#xff0c;我们将更仔细地查看一些必要的Golang库&#…

心血管疾病药物不良反应不容忽视,华大基因基因检测辅助降低风险!

随着医疗技术的不断进步&#xff0c;个体化用药已经成为药物治疗的新趋势。在此趋势下&#xff0c;华大基因基因检测基于药物基因组学的药物选择和个性化用药方案&#xff0c;为心血管疾病患者的临床治疗提供了新机会&#xff0c;同时可以更好地帮助患者控制心血管疾病&#xf…

数据结构之栈的讲解(源代码+图解+习题)

我们在学习过顺序表和链表之后&#xff0c;了解了使用数组存储数据&#xff0c;使用结构体来存储数据和有关的指针&#xff0c;这些都是底层的东西&#xff0c;链表是靠指针的链接&#xff0c;顺序表是靠数组的下标才能得以实现增删查改。众多数据结构其实底层都离不开数组&…

HTML简单实现v-if与v-for与v-model

Vue启动&#xff01;&#xff01; 首先VIewModel将View和Model连接一起&#xff0c;Model的数据改变View的数据也变 使用Visual Studio Code 启动Vue需要vue.js插件和导入CDN(包) vue.js插件&#xff1a;CTRL shift x 在搜索栏搜 索vue.js安装即可 CDN&#xff1a; http…

使用Terraform管理已经存在的kubernates和默认的节点池

背景&#xff1a; 通过terraform resource "alicloud_cs_managed_kubernetes" "k8s" {...}创建集群时&#xff0c;会产生一个默认的节点池default-nodepool&#xff0c;但是如何去修改这个默认节点池的信息呢&#xff1f; 解决思路&#xff1a; 因为Ter…

2021美亚个人赛复现1

Individual_Container.zip.001下载以后显示是一个压缩包格式&#xff08;解压密码&#xff1a;MeiyaCup2021&#xff09; 解压得到Individual_Container加密容器&#xff0c;赛题存储在这里面 挂载密码HfsCk]<eUqc5Q{(DG$ugiGlt8ezGdaZ>!pQC-H\5BAc^gBo/^qq)/i21ufiNH&…