Hystrix熔断器环境搭建及详解

2024-01-11 15:36

本文主要是介绍Hystrix熔断器环境搭建及详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Hystrix介绍

1. Hystrix含义

Hystrix,英文意思是豪猪,全身是刺,刺是一种保护机制。Hystrix也是Netflix公司的一款组件。

2. Hystrix作用

实现服务熔断降级处理,保护微服务,防止雪崩效应发生,以增强系统的稳定性和弹性。
以下功能会在下面后续举例讲解:

  • 隔离依赖:Hystrix 可以通过将每个依赖服务放在单独的线程池中来隔离依赖操作,防止某个依赖的故障或延迟影响到整个系统。

  • 服务降级:Hystrix 可以根据配置的降级策略,在被依赖服务不可用被依赖服务响应时间过长时,快速返回一个备选的响应结果,从而避免用户长时间等待或系统崩溃的情况。

  • 快速失败:当调用依赖服务出现错误时,Hystrix 可以快速失败并立即返回错误,而不是等待超时。

  • 断路器模式【熔断】:Hystrix 实现了断路器模式,可以监控依赖服务的状态,当错误率超过阈值时,会打开断路器,后续请求将被快速失败,而不会继续尝试调用依赖服务,从而减少对故障服务的访问。

  • 资源限制:Hystrix 可以对依赖服务的调用进行限流和并发控制,防止系统因为过多的请求导致资源耗尽。

  • 实时监控和指标收集:Hystrix 提供了丰富的实时监控和指标收集功能,可以通过 Hystrix 仪表板来查看依赖服务的健康状况、错误率、响应时间等指标,从而帮助开发人员及时发现和解决问题。

总的来说,Hystrix 可以提高分布式系统的容错性和弹性,通过隔离、降级、快速失败、断路器等机制,保护系统免受故障和延迟的影响,并提供实时监控和指标收集功能,方便开发人员进行故障诊断和性能优化。

3. 雪崩效应

当单个服务出现问题,调用这个服务的请求就出现线程阻塞,此时若有大量的请求涌入,容器的线程资源就会被消耗完毕导致服务瘫痪。

  1. 微服务中,一个请求可能需要调用多个微服务接口才能实现,会形成复杂的调用链路。
  2. 如果某服务出现异常,请求阻塞,用户得不到响应,容器中线程不会释放,于是越来越多用户请求堆积,越来越多线程阻塞。
  3. 单服务器支持线程和并发数有限,请求如果一直阻塞,会导致服务器资源耗尽,从而导致所有其他服务都不可用,从而形成雪崩效应。

4. 雪崩解决方案

预防、解决服务雪崩有三种方法:

  • 服务降级
  • 服务熔断
  • 服务限流
4.1. 服务降级

服务调用方调用服务提供方方法,服务方法内部出现异常时返回一个响应(fallback)给调用方,而不是长时间等待或者直接抛出无法处理的异常。例如:“服务器忙,请稍后再试!”

服务降级的触发条件是人为规定的,触发条件如下:

  • 报异常
  • 超时
  • 通信线程池被打满
4.2. 服务熔断

直接拒绝访问,快速返回一个开发者自定义的“异常信息”。

4.3. 服务限流

限制一个时间段内能够通行的请求数量。

降级和熔断的区别
熔断:熔断后请求不会再进调用服务的方法体,直接将链路断开,此后的每次请求都会直接被抛给fallback。
降级:降级后请求依然会进调用服务的方法体,每次请求都会先试图去调用服务,只是服务自己察觉到自己可能出问题了从而拒绝服务,然后再将请求转给fallback。直接转发到即当服务的调用出现超时、异常等情况时,返回一个响应(fallback)。降级可以用在服务调用的全链路上的任意位置,不过为了使用规范,一般建议用在提供方(让服务自己管好自己)。

二、实战案例

使用hystrix时,版本一定要选还在Netflix时的版本号,本文选择Hoxton版本以及其对应的spring boot 2.2.X或2.3.X

为了方便,项目在我们之前的zuul或者搭建eureka章节搭建的项目框架上进行开发。在之前的项目上开发并不意味着Hystrix要依赖于Eureka或者zuul,Hystrix可以独立应用。

在userservice服务中写一个错误,验证服务降低策略。

@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/login")public String login(){int res = 1/0;return "8080 login success";}
}

此时我们重启服务,访问orderservice服务,这个服务会调用userservice服务,有两个userservice服务,其中8080服务是有异常的。当订单服务调用到部署在8080端口的服务时就会报500错误。
在这里插入图片描述

现在我们来看下如何实现服务降低,在userservice服务异常时,快速返回一个备选的响应结果,从而避免用户长时间等待或系统崩溃的情况。

1. 引入依赖

在orderservice服务中引入依赖。

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

2. 熔断降级处理

2.1. 单点响应

适用:该方法是核心业务需要针对该方法设置一个单独的fallback。

@RestController
@RequestMapping("order")
public class OrderController {@Bean@LoadBalancedpublic RestTemplate getRestTemplate(){return new RestTemplate();}@Autowiredprivate RestTemplate restTemplate;@GetMapping("/info")@HystrixCommand(fallbackMethod = "orderHandleException")public String getOrderInfo(){String url = "http://userservice/user/login";String info = restTemplate.getForObject(url, String.class);return "订单滴滴:" + info;}public String orderHandleException(){return "订单服务调用失败";}
}

添加@HystrixCommand(fallbackMethod = "orderHandleException"),指定了异常发生时的备选方案,异常发生会去调用orderHandleException方法。我们这里使用了fallabck为单点响应,即每个服务接口单独定义异常响应。目前我们没有进行任何配置文件的配置,但hystrix有默认的配置规则,不配置的情况下,默认配置规则也会生效,配置文件中的配置是全局的,我们也可以在方法上指定该方法的熔断策略。

 @GetMapping("/info")@HystrixCommand(fallbackMethod = "orderHandleException", commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")})public String getOrderInfo(){String url = "http://userservice/user/login";String info = restTemplate.getForObject(url, String.class);return "订单滴滴:" + info;}
2.2. 默认响应

我们上面的配置是针对单个方法的响应,也可以定义一个类中所有方法的默认fallback,来统一处理服务降级。

@RestController
@RequestMapping("order")
@DefaultProperties(defaultFallback = "globalFallback")
public class OrderController {@Bean@LoadBalancedpublic RestTemplate getRestTemplate(){return new RestTemplate();}@Autowiredprivate RestTemplate restTemplate;@GetMapping("/info")@HystrixCommand(fallbackMethod = "orderHandleException", commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")})public String getOrderInfo(){String url = "http://userservice/user/login";String info = restTemplate.getForObject(url, String.class);return "订单滴滴:" + info;}@GetMapping("/didi")@HystrixCommandpublic String getOrderInfo2(){int res = 1/0;return "订单didi";}public String globalFallback(){return "订单服务调用失败_gloabl";}public String orderHandleException(){return "订单服务调用失败";}
}

在这里插入图片描述

2.3. 全局响应

无论是单点响应还是默认响应,响应代码和业务代码都耦合在一起,全局响应将响应放在OpenFeign调用侧,使得业务代码和响应代码解耦。

依赖:OpenFeign的依赖中包含了hystrix,导入OpenFeign后不用单独导入hystrix。

在需要降级的服务上进行下面配置:orderservice
pom.xml

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

application.yml

feign:hystrix:enabled: true

orderservice服务改造:

@RestController
@RequestMapping("order")
public class OrderController {@Resourceprivate UserServiceClient userServiceClient;@GetMapping("/info")public String getOrderInfo() {String info = userServiceClient.login();return "订单滴滴:" + info;}
}

新增feign包 ,创建 UserServiceClient类:

@FeignClient(name = "userservice", fallback = UserServiceFallback.class)
public interface UserServiceClient {@GetMapping("/user/login")String login();
}

这个类实现了服务远程调用,fallback指定了远程调用服务时异常触发服务降级。
新增fallback包,创建UserServiceFallback方法进行服务降级处理。

@Component
public class UserServiceFallback implements UserServiceClient {@Overridepublic String login() {return "用户服务调用失败";}
}

启动类开启服务远程调用:@EnableFeignClients

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

重启服务,orderservice服务调用会轮询调用8080和8081端口的userservice服务,如果8081端口抛异常,会直接进行服务降级处理,返回用户服务调用失败给用户,如果8081端口超时则不会立马进行服务降级处理,而是会报504,直到满足默认的熔断配置规则才会触发服务熔断,才会直接返回用户服务调用失败给用户。

3. 开启熔断降级

在启动类上添加开启熔断和降级注解

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class ConsumerServerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerServerApplication.class, args);}
}

启动服务,再次访问orderservice服务。订单服务还是有可能成功的,因为8081端口的服务没有问题,异常是我们人为制造的。
在这里插入图片描述
目前的操作中并不需要进行配置文件配置,默认的熔断策略是5秒内20次调用失败熔断器开启5秒,在这5秒内所有请求直接返回fallback。

4. 熔断策略配置

在orderservice服务的配置文件中进行配置熔断策略:
在application.yml中,注释可能会导致错误,报错将错误删除即可。

# 配置熔断策略:
hystrix:command:default:circuitBreaker:# 强制打开熔断器 默认false关闭的。测试配置是否生效# forceOpen: false# 触发熔断错误比例阈值,默认值50% 10个请求有5个被拒绝访问,则开启熔断errorThresholdPercentage: 50# 熔断后休眠时长,默认值5秒 熔断器开启5s后,再关闭sleepWindowInMilliseconds: 10000# 熔断触发最小请求次数,默认值是20 累计请求20次无响应,开启熔断requestVolumeThreshold: 10

上面的配置就是10个请求有5个失败进行服务降级就会开启熔断器,熔断器开启10秒,如果在这个时间段内有新的请求发生,它们将不会被直接转发到服务,而是由 fallback 方法来处理,从而达到服务降级的目的。配置文件的配置是全局生效,配置也可以在对应的方法上,针对该方法配置对应的降级熔断的策略,上面已经介绍过了。

5. 服务超时

1/0从8080端口的userservice删去,使服务正常。
在8081端口的userservice中进行一个休眠操作,休眠3秒:

@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/login")public String login(){//演示熔断超时,服务降级try {System.out.println("8081服务睡了3秒");Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}return "8081 login success";}
}

此时重启服务,访问orderservice会发现,会发现报504错误,也就是网关超时。我们虽然使用了网关zuul,但504错误并不是因为配置了网关才会报504错误,即使不配置网关,客户端直接请求上游服务器,而上游服务器的响应时间过长,也可能导致 HTTP 504 错误。此外,还有一些其他的因素,比如网络连接问题、DNS 问题等,也可能导致 HTTP 504 错误。

# 配置熔断策略:
hystrix:command:default:circuitBreaker:# 触发熔断错误比例阈值,默认值50% 10个请求有5个被拒绝访问,则开启熔断errorThresholdPercentage: 50# 熔断后休眠时长,默认值5秒 熔断器开启5s后,在关闭sleepWindowInMilliseconds: 10000# 熔断触发最小请求次数,默认值是20 累计请求20次无响应,开启熔断requestVolumeThreshold: 10execution:isolation:thread:# 熔断超时设置,默认为1秒 过了超时时间后,做服务降级,给用户的请求返回设置的默认值timeoutInMilliseconds: 2000

修改服务提供者方法,休眠3秒钟,这时超时时间是2s,过了超时时间仍调用不到服务,(满足熔断策略配置规则)此时触发熔断。如果休眠时间小于超时时间,那么不会触发熔断,而是一直报504异常。即使不设置熔断超时时间,默认的熔断时间就是1秒了,所以一般来说都会触发熔断。

这篇关于Hystrix熔断器环境搭建及详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/594843

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

安装nodejs环境

本文介绍了如何通过nvm(NodeVersionManager)安装和管理Node.js及npm的不同版本,包括下载安装脚本、检查版本并安装特定版本的方法。 1、安装nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash 2、查看nvm版本 nvm --version 3、安装

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

高并发环境中保持幂等性

在高并发环境中保持幂等性是一项重要的挑战。幂等性指的是无论操作执行多少次,其效果都是相同的。确保操作的幂等性可以避免重复执行带来的副作用。以下是一些保持幂等性的常用方法: 唯一标识符: 请求唯一标识:在每次请求中引入唯一标识符(如 UUID 或者生成的唯一 ID),在处理请求时,系统可以检查这个标识符是否已经处理过,如果是,则忽略重复请求。幂等键(Idempotency Key):客户端在每次

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

pico2 开发环境搭建-基于ubuntu

pico2 开发环境搭建-基于ubuntu 安装编译工具链下载sdk 和example编译example 安装编译工具链 sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib 注意cmake的版本,需要在3.17 以上 下载sdk 和ex