SpringCloud第九章,升级篇,服务降级、熔断与实时监控Hystrix

本文介绍了SpringCloud中服务降级、熔断的概念,通过案例详细展示了如何在cloud-provider-hystrix-payment-8001和cloud-consumer-feign-hystrix-order-80中实现Hystrix服务降级和熔断。同时讨论了解决代码膨胀和业务逻辑混淆的方法,并提及服务限流的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringCloud第九章,升级篇,服务降级、熔断与实时监控Hystrix

一、Hystrix概述

1、服务雪崩

在这里插入图片描述

服务雪崩service avalanche:

假设服务存在如上调用,service a流量波动很大,流量经常会突然性增加!那么在这种情况下,就算Service A能扛得住请求,Service B和Service C未必能扛得住这突发的请求。
此时,如果Service C因为抗不住请求,变得不可用。那么Service B的请求也会阻塞,慢慢耗尽Service B的线程资源,Service B就会变得不可用。紧接着,对Service A的调用就会占用越来越多的资源,进而引起系统崩溃。

如上,一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩。

服务降级和服务熔断可以视为解决服务雪崩的手段。

2、服务熔断

当下游的服务因为某种原因突然变得不可用或者响应过慢,上游服务为了保证自己服务的可用性,不再继续调用目标服务,直接返回快速释放资源。
如果目标服务好转则恢复调用。

目前流行的熔断器很多,例如阿里出的Sentinel(之后会在博客中介绍),以及最多人使用的Hystrix。

Hystrix配置如下:
##滑动窗口的大小,默认为20
circuitBreaker.requestVolumeThreshold 
##过多长时间,熔断器再次检测是否开启,默认为5000,即5s钟
circuitBreaker.sleepWindowInMilliseconds 
##错误率,默认50%
circuitBreaker.errorThresholdPercentage

每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。直到5s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。

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

3、服务降级

两种场景:
a、当下游服务由于某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放服务器资源,增加响应速度。
b、当下游服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速回馈用户。

简单说:
	服务器很忙,请稍后再试,不让客户端等待并立刻返回一个友好提示fallback.

4、服务限流

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

5、服务降级和熔断的区别

相同点:
目标一致 都是从可用性和可靠性出发,为了防止系统崩溃;
用户体验类似 最终都让用户体验到的是某些功能暂时不可用;

不同点:
触发原因不同 服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑; 
管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始)
实现方式不太一样,服务降级具有代码侵入性(由控制器完成/或自动降级),熔断一般称为自我熔断。

二、案例

1、构建cloud-provider-hystrix-payment-8001

POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud_2020</artifactId>
        <groupId>com.lee.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-hystrix-payment-8001</artifactId>

    <dependencies>
        <!--hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>com.lee.springcloud</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

application.yml

server:
  port: 8001
spring:
  application:
    name: cloud-provider-hystrix-payment
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka

主启动类:

@SpringBootApplication
@EnableEurekaClient
public class PaymentHystrixMain8001 {
   

    public static void main(String[] args) {
   
        SpringApplication.run(PaymentHystrixMain8001.class,args);
    }
}

service

@Service
public class PaymentService {
   

    //正常访问
    public String paymentInfo_ok(Integer id){
   
        return "thread:"+Thread.currentThread().getName()+"  payment ok id : "+id+"  ^_^";
    }

    //访问超时
    public String paymentInfo_timeout(Integer id) throws InterruptedException {
   
        int timeNumber = 3;
        TimeUnit.SECONDS.sleep(timeNumber);
        return "thread:"+Thread.currentThread().getName()+"  payment timeout id : "+id+"  ╥﹏╥";
    }
}

controller

@RestController
@Slf4j
public class PaymentController {
   

    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String servicePort;

    //正常访问
    @GetMapping("/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id) {
   
        String result = paymentService.paymentInfo_ok(id);
        return result;
    }

    //超时访问
    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException {
   
        String result = paymentService.paymentInfo_timeout(id);
        return result;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值