SpringCloud微服务项目实战 - 限流、熔断、降级处理

本文主要是介绍SpringCloud微服务项目实战 - 限流、熔断、降级处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们知道,在分布式微服务项目体系中,一个系统是由若干个子服务模块组成,这若干个子服务相互调用协同工作,对外输出服务使得整个系统运作。

7bd27fec4d4dc5c950be19b65426fdad.png

由于服务之间的相互协作调用,所以要保证整个系统完整运行,就得保证每个服务模块运行良好。但在实际庞大的分布式体系中,我们难免遇到某个服务阻塞或挂起等情况。假设客户在下单时,需要调用订单服务的接口,而订单服务有依赖了客户服务、商品服务、库存服务等,在下单时如果依赖的某个服务发生异常(请求超时),所有的请求就阻塞在这个依赖服务上,则会造成整个下单接口调用失败。就会导致整个系统下单不可用甚至雪崩,那这种问题如何解决呢?这将是我们文章里今天要讨论的话题。

在SpringCloud分布式项目中,为了保证服务的高可用,Netflix的组件Hystrix可以将这些请求隔离,针对服务限流,当某个服务不可用时能够熔断并降级,防止级联故障。

什么是Hystrix?

Hystrix中文翻译 豪猪,由于其背上长满了棘刺,从而拥有自我保护的能力。Hystrix作为Netflix开源的一款容错框架,同样具有自我保护能力。

它是一个用于处理分布式系统的延迟和容错的开源库, 在分布式系统中,许多不可避免的服务调用失败, 如超时/异常等。Hystrix 能够保证在一个依赖出现问题的情况下,不会导致整体系统服务的失败、避免级联故障、提高系统的弹性。

12a96b44fe0289bff6694192e8a66fce.png

"断路器" 本身是一种开关装置,当有服务发生故障后,通过断路器的故障监控(类似保险熔断),向调用方返回一个符合预期的、可处理的备选响应(FallBack) ,而不是等待/超时或抛出异常,这样就保证了服务调用方的线程不会长时间,不必要地占用,从而避免了故障在分布式系统无线的蔓延,防止了雪崩效应的发生。

为了实现容错和自我保护,我们先看一下Hystrix的设计和实现。

Hystrix设计目标:

  • 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的

  • 阻止故障的连锁反应

  • 快速失败并迅速恢复

  • 回退并优雅降级

  • 提供近实时的监控与告警

Hystrix遵循的设计原则:

  • 防止任何单独的依赖耗尽资源(线程)

  • 过载立即切断并快速失败,防止排队

  • 尽可能提供回退以保护用户免受故障

  • 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响

  • 通过近实时的指标,监控和告警,确保故障被及时发现

  • 通过动态修改配置属性,确保故障及时恢复

  • 防止整个依赖客户端执行失败,而不仅仅是网络通信

Hystrix实现限流熔断降级

1,通过Command实现

首先添加Hystrix的pom依赖:

f3c9e07da8f749c3ba8ca74257e929e0.png

配置Hystrix属性(yml文件):

# Hystrix 默认加载的配置文件 - 限流、 熔断
hystrix:# 线程池大小threadpool:default:coreSize: 1maxQueueSize: 200queueSizeRejectionThreshold: 2# 限流策略#如果没有定义HystrixThreadPoolKey,HystrixThreadPoolKey会默认定义为HystrixCommandGroupKey的值userGroup:coreSize: 1maxQueueSize: -1queueSizeRejectionThreshold:  800userThreadPool:coreSize: 1maxQueueSize: -1queueSizeRejectionThreshold:  800# 执行策略
# 资源隔离模式,默认thread。还有一种叫信号量command:default:execution:isolation:strategy: THREAD# 是否打开超时timeout:enabled:  true# 超时时间,默认1000毫秒isolation:thread:timeoutInMilliseconds:  15000# 超时时中断线程interruptOnTimeout: true# 取消时候中断线程interruptOnFutureCancel: false# 信号量模式下,最大并发量semaphore:maxConcurrentRequests:  2# 降级策略# 是否开启服务降级fallback:enabled:  true# fallback执行并发量isolation:semaphore:maxConcurrentRequests:  100# 熔断策略# 启用/禁用熔断机制circuitBreaker:enabled:  true# 强制开启熔断forceOpen:  false# 强制关闭熔断forceClosed:  false# 前提条件,一定时间内发起一定数量的请求。也就是5秒钟内(这个5秒对应下面的滚动窗口长度)至少请求4次,熔断器才发挥起作用。默认20requestVolumeThreshold: 4# 错误百分比。达到或超过这个百分比,熔断器打开。比如:5秒内有4个请求,2个请求超时或者失败,就会自动开启熔断errorThresholdPercentage: 50# 10秒后,进入半打开状态(熔断开启,间隔一段时间后,会让一部分的命令去请求服务提供者,如果结果依旧是失败,则又会进入熔断状态,如果成功,就关闭熔断)。默认5秒sleepWindowInMilliseconds:  10000# 度量策略# 5秒为一次统计周期,术语描述:滚动窗口的长度为5秒metrics:rollingStats:timeInMilliseconds: 5000# 统计周期内 度量桶的数量,必须被timeInMilliseconds整除。作用:numBuckets: 10# 是否收集执行时间,并计算各个时间段的百分比rollingPercentile:enabled:  true# 设置执行时间统计周期为多久,用来计算百分比timeInMilliseconds: 60000# 执行时间统计周期内,度量桶的数量numBuckets: 6# 执行时间统计周期内,每个度量桶最多统计多少条记录。设置为50,有100次请求,则只会统计最近的10次bucketSize: 100# 数据取样时间间隔healthSnapshot:intervalInMilliseconds: 500# 设置是否缓存请求,request-scope内缓存requestCache:enabled:  false# 设置HystrixCommand执行和事件是否打印到HystrixRequestLog中equestLog:enabled:  falseuserCommandKey:execution:isolation:thread:timeoutInMilliseconds: 5000

编写Command类:

2b19e30b020d3bc6ab43d4e3f26dd30b.png

40e886807a930256d31434a0ed09bb89.png

在服务提供者中写调用的接口:

fc28880bdddfc94553726599371d0be6.png

在当前服务中添加接口:

188e49120dec0d7fe9a2d6c4c8d6ceb2.png

这里HystrixCommand的每次都必须使用新的对象(保证每次请求都是一个新的线程)调用其execute方法,而不能使用单例。否则会提示

Thisinstance can only be executed once.Please instantiate a new instance.

服务降级

请求order-service的/order/exception接口,因为customer-service的/customer/exception会随机抛出运行时异常。当服务异常时,将返回“服务已降级,暂不可用”,而服务正常时将返回ok。这说明我们的服务因为异常降级。

请求/order/timeout接口时,“服务已降级,暂不可用”。如果修改hystrix.command.userCommandKey.execution.isolation.thread.timeoutInMilliseconds=10000,Hstrix限制的超时时间大于接口的返回时长,就能成功返回ok。这个例子说明服务因为请求超时降级了。

服务限流

在分布式环境中,每个服务模块的请求承载量是有限的,因此为保证服务正常,我们会限制来自客户端请求的并发数。可以通过semaphore.maxConcurrentRequests.coreSize.maxQueueSize和queueSizeRejectionThreshold设置信号量模式下的最大并发量、线程池大小、缓冲区大小和缓冲区降级阈值。在示例中我们作如下设置

  • #不设置缓冲区,当请求数超过coreSize时直接降级

  • hystrix.threadpool.userThreadPool.maxQueueSize=-1

  • #超时时间大于我们的timeout接口返回时间

  • hystrix.command.userCommandKey.execution.isolation.thread.timeoutInMilliseconds=10000

这个时候当连续多次请求/order/timeout接口,在第一个请求还没有成功返回时,查看输出日志可以发现只有第一个请求正常的进入到order-service的接口中,其它请求会直接返回降级信息。这样我们就实现了对服务请求的限流。

服务熔断

在yml配置中开启熔断,并且以5秒为度量周期,当5秒内请求超过4个错误超过50%时,就会开启熔断器,所有的请求都会直接降级,如果5秒内的请求不够4个,就算有三个请求且全部失败也不会开启熔断器。10秒后熔断器进入半打开状态会让一部分请求向服务端发起调用,如果成功关闭熔断器,否则再次进入熔断状态。

0457a9147783d3c7364b29b2e51310e3.jpeg

我们对order-serivce的/order/exception连续发起请求(5秒内至少4次),当我们的请求异常超过50%时,服务会直接返回降级信息。
实际上当服务异常、超时、宕机并满足熔断条件时,都会开启熔断。

2,通过FeignClient集成实现

前面通过Command要对每个接口写command类,很是麻烦,但使用Hystrix和Feign的集成就十分方便了。需要在启动类中添加注解@EnableCircuitBreaker启用熔断机制。

5758d6cb2edd11d8d15a12040518c01e.png

添加Feign客户端和降级类

675c89d206f52b513d9a4cb49aab3b28.png

降级类:

86154c313f54500eb7b423252226d41b.png

再在Controller添加接口:

57d4a0532f563592cfc6dce833aeb328.png

今天要说的就讲到这里,我们下一篇继续讲SpringCloud微服务项目实战。代码我也讲上传到github,请注意后续动态。

推荐阅读:

SpringCloud微服务项目实战 -  API网关Gateway详解实现

SpringCloud微服务项目实战 - 网关zuul详解及搭建

SpringCloud微服务项目实战 - 微服务调用详解(附面试题)

SpringCloud微服务项目实战,服务注册与发现(附面试题)

Spring Cloud微服务项目实战--Eureka服务搭建

扫码关注公众号,发送关键词获取相关资料:
发“Springboot”领取电商项目实战源码;
发“SpringCloud”领取学习实战资料;

0c57f7457941938f4add909f5dd2e145.jpeg

这篇关于SpringCloud微服务项目实战 - 限流、熔断、降级处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Mac系统下卸载JAVA和JDK的步骤

《Mac系统下卸载JAVA和JDK的步骤》JDK是Java语言的软件开发工具包,它提供了开发和运行Java应用程序所需的工具、库和资源,:本文主要介绍Mac系统下卸载JAVA和JDK的相关资料,需... 目录1. 卸载系统自带的 Java 版本检查当前 Java 版本通过命令卸载系统 Java2. 卸载自定

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

Java Spring ApplicationEvent 代码示例解析

《JavaSpringApplicationEvent代码示例解析》本文解析了Spring事件机制,涵盖核心概念(发布-订阅/观察者模式)、代码实现(事件定义、发布、监听)及高级应用(异步处理、... 目录一、Spring 事件机制核心概念1. 事件驱动架构模型2. 核心组件二、代码示例解析1. 事件定义

SpringMVC高效获取JavaBean对象指南

《SpringMVC高效获取JavaBean对象指南》SpringMVC通过数据绑定自动将请求参数映射到JavaBean,支持表单、URL及JSON数据,需用@ModelAttribute、@Requ... 目录Spring MVC 获取 JavaBean 对象指南核心机制:数据绑定实现步骤1. 定义 Ja

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

spring中的ImportSelector接口示例详解

《spring中的ImportSelector接口示例详解》Spring的ImportSelector接口用于动态选择配置类,实现条件化和模块化配置,关键方法selectImports根据注解信息返回... 目录一、核心作用二、关键方法三、扩展功能四、使用示例五、工作原理六、应用场景七、自定义实现Impor

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项