SpringCloud-服务降级_服务熔断_服务限流(Hystrix)

 

Hystrix

https://github.com/Netflix/Hystrix/

概述

前言

分布式系统面临的问题

复杂的分布式体系结构的应用 可能有很多个依赖,每个依赖在某些时刻将不可避免的失败;

服务雪崩

 

what

1、Hystrix是一个 处理分布式系统的延迟/容错的 开源库;

2、在分布式系统里,许多依赖不可避免的会调用失败(超时、异常...),Hystrix能保证在一个依赖出现异常的情况下,不会导致服务整体失败,避免级联故障,保证分布式系统的弹性;

3、"断路器"本身是一种开关,当某个服务单元发生故障时,通过断路器的故障检测 向调用方 返回一个符合预期、备选的FallBack,而不是长时间的等待或抛出调用方无法处理的异常;

    这样保证了服务调用方的线程 不会被长时间占用,从而避免故障在分布式系统中蔓延,乃至雪崩;

停更维护怎么办

 

解决

 

 resilience4j、 

Hystrix概念

服务降级

what

当服务不可用时,给调用方的兜底响应;

什么情况会发生服务降级?

程序异常、超时、服务熔断触发服务降级、线程池满

服务熔断

what

当服务达到峰值,直接拒绝访问,给调用方一个兜底响应;

服务限流

what

当服务突然接收到大量请求时,限制单位时间内可处理的数量;

主要的问题

超时导致服务变慢

解决

超时不再继续等待

出错(服务宕机/程序出错)

解决

出错有兜底

解决方案

1、服务提供方超时/运行报错/宕机 -> 调用方不能卡死等待,必须有服务降级;

 

2、服务提供方正常,调用方自己故障/有自己要求(自己等待时间<服务提供方时间) ->  调用方自己服务降级;

How

服务降级

一般服务降级用在 服务调用方;

服务提供方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
 
 
@EnableCircuitBreaker // 开启Hystrix
@EnableEurekaClient
@SpringBootApplication
public class HystrixPaymentStarter8001 {
 
    public static void main(String[] args) {
        SpringApplication.run(HystrixPaymentStarter8001.class, args);
    }
 
}
 
 
@RestController
public class Controller {
 
    @Autowired
    PaymentService paymentService;
 
    @HystrixCommand(fallbackMethod = "timeOutFallback", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    @GetMapping(value = "/hystrix/timeout")
    public String timeout(){
        int i = 1/0;  // 运行报错
 
        return paymentService.timeout(); // 服务超时
    }
 
    /**
     * 服务降级 Fallback方法
     * @return
     */
    public String timeOutFallback(){
        return Thread.currentThread().getName() + "payment系统繁忙,请稍后再试!  o(╥﹏╥)o";
    }
 
 
}

  

服务调用方 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
 
 
#开启Feign的Hystrix
feign:
  hystrix:
    enabled: true
 
 
@EnableHystrix // 开启Hystrix
@EnableFeignClients // 开启Feign支持
@SpringBootApplication
public class OpenFeignHystrixOrderStarter80 {
 
    public static void main(String[] args) {
        SpringApplication.run(OpenFeignHystrixOrderStarter80.class, args);
    }
 
}
 
 
 
@RestController
public class OrderController {
 
    @Autowired
    private PaymentService paymentService;
 
    @HystrixCommand(fallbackMethod = "timeOutFallback", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    })
    @GetMapping(value = "/order/timeout")
    public String timeOut(){
        int a = 1/0; // 程序运行报错
 
        return paymentService.timeOut();
    }
 
    /**
     * 服务降级 Fallback方法
     * @return
     */
    public String timeOutFallback(){
        return Thread.currentThread().getName() + "由于 payment系统繁忙,请稍后再试!  o(╥﹏╥)o";
    }
 
}

  

 

全局Fallback

标记@HystrixCommand方法才会进行服务降级:

  有自定义的fallbackMethod,按自定义处理;

  无自定义的fallbackMethod,按全局处理;

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@DefaultProperties(defaultFallback = "globalFallback"// 全局fallback定义
@RestController
public class OrderController {
 
    @Autowired
    private PaymentService paymentService;
 
    @HystrixCommand  // 全局服务降级
    @GetMapping(value = "/order/ok")
    public String ok(){
        int a = 1/0; // 程序运行报错
 
        return paymentService.ok();
    }
 
    @HystrixCommand(fallbackMethod = "timeOutFallback", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    })
    @GetMapping(value = "/order/timeout")
    public String timeOut(){
        int a = 1/0; // 程序运行报错
 
        return paymentService.timeOut();
    }
 
    /**
     * 服务降级 Fallback方法
     * @return
     */
    public String timeOutFallback(){
        return Thread.currentThread().getName() + "由于 payment系统繁忙,请稍后再试!  o(╥﹏╥)o";
    }
 
    /**
     * 服务降级 globalFallback方法
     * @return
     */
    public String globalFallback(){
        return Thread.currentThread().getName() + "全局Fallback payment系统繁忙,请稍后再试!  o(╥﹏╥)o";
    }
 
}

  

fallback方法与业务代码解耦 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#开启Feign的Hystrix
feign:
  hystrix:
    enabled: true
 
 
 
@Component
public class PaymentFallbackService implements PaymentService{
    @Override
    public String ok() {
        return "PaymentFallbackService.ok O(∩_∩)O";
    }
 
    @Override
    public String timeOut() {
        return "PaymentFallbackService.timeOut O(∩_∩)O";
    }
}
 
 
@Component
@FeignClient(value = "eureka-hystrix-payment-service", fallback = PaymentFallbackService.class)
public interface PaymentService {
 
    @GetMapping(value = "/hystrix/ok")
    String ok();
 
    @GetMapping(value = "/hystrix/timeout")
    String timeOut();
 
}
 
 
@RestController
public class OrderController {
 
    @Autowired
    private PaymentService paymentService;
 
    @GetMapping(value = "/order/ok")
    public String ok(){
        return paymentService.ok();
    }
 
}
 
 
@EnableHystrix // 开启Hystrix
@EnableFeignClients // 开启Feign支持
@SpringBootApplication
public class OpenFeignHystrixOrderStarter80 {
 
    public static void main(String[] args) {
        SpringApplication.run(OpenFeignHystrixOrderStarter80.class, args);
    }
 
}

 

服务熔断 

https://martinfowler.com/bliki/CircuitBreaker.html

熔断机制是什么

 

 

应对雪崩效应的 一种微服务链路保护机制;

当扇出链路的某个微服务不可用或响应时间过长,进行服务降级,进而熔断该节点微服务的调用,快速返回错误的响应信息;

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

实现

在SpringCloud中,使用Hystrix实现;

Hystrix会监控微服务之间的调用情况,当失败的调用达到一定的阈值,缺省是5秒内20次失败,就会启动熔断机制;

Hystrix服务熔断机制注解 @HystrixCommand;

How

服务降级 -> 服务熔断 -> 恢复服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
 
 
 
server:
  port: 8001
 
spring:
  application:
    name: eureka-hystrix-payment-service
 
eureka:
  client:
    register-with-eureka: true #是否向注册中心注册自己
    fetchRegistry: true #是否从注册中心抓取已有的注册信息 默认true,集群必须设置为true
    service-url:
      defaultZone: http://localhost:7001/eureka/   #单机版
 
 
 
 
@EnableCircuitBreaker // 开启Hystrix
@EnableEurekaClient
@SpringBootApplication
public class HystrixPaymentStarter8001 {
 
    public static void main(String[] args) {
        SpringApplication.run(HystrixPaymentStarter8001.class, args);
    }
 
}
 
 
 
 
 
package com.an;
 
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
 
/**
 * @author apy
 * @description
 * @date 2022/8/5 10:57
 */
@RestController
public class Controller {
 
    // 服务熔断
 
    @HystrixCommand(fallbackMethod = "circuitBreakerFallback", commandProperties = {
            // 在10s访问时间内,进行10次访问,失败率达到60%后,进行熔断
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),  // 是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // 请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),   //  时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")    //  失败率达到多少后跳闸
    })
    @GetMapping(value = "/hystrix/circuitBreaker/{id}")
    public String circuitBreaker(@PathVariable(value = "id") Long id){
        if (id < 0){
            throw new IllegalArgumentException("param error");
        }
        return Thread.currentThread().getName() + "success";
    }
 
    /**
     * 服务降级 Fallback方法
     * @param id
     * @return
     */
    public String circuitBreakerFallback(Long id){
        return "circuitBreakerFallback...id:"+ id;
    }
}

 

熔断类型 

Open

  请求不再调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到所设时钟进入HalfOpen状态;

  不会调用主逻辑,直接调用降级fallback;

Half Open

  部分请求根据规则调用当前服务,如果请求成功且符合规则,任务当前服务恢复正常,关闭熔断;

Close

  不会对服务进行熔断;

 

服务限流

...

Hystrix工作流程

https://github.com/Netflix/Hystrix/wiki/How-it-Works

Hystrix图形化Dashboard

what

Hystrix还提供了 图形化Dashboard,会持续记录所有通过Hystrix发起的请求的执行信息,并以图形报表的形式展示;

Netflix通过hystrix-metrics-event-stream实现了以上监控;

SpringCloud也整合了Hystrix Dashboard,对监控内容转化为图形化界面;

How

Hystrix Dashboard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
 
 
 
server:
  port: 9001
 
 
 
@EnableHystrixDashboard
@SpringBootApplication
public class HystrixDashboardStarter9001 {
 
    public static void main(String[] args) {
        SpringApplication.run(HystrixDashboardStarter9001.class, args);
    }
 
}
 
 
 
http://localhost:9001/hystrix

  

Hystrix Dashboard监控8001微服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
 
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>    被监控的服务必须的依赖
        </dependency>
 
 
@EnableCircuitBreaker // 开启Hystrix
@EnableEurekaClient
@SpringBootApplication
public class HystrixPaymentStarter8001 {
 
    public static void main(String[] args) {
        SpringApplication.run(HystrixPaymentStarter8001.class, args);
    }
 
    /**
     * 为服务监控而配置,与容错本身无关;
     * @return
     */
    @Bean
    public ServletRegistrationBean getServlet(){
 
        ServletRegistrationBean bean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
        bean.setLoadOnStartup(1);
        bean.addUrlMappings("/hystrix.stream");
        bean.setName("HystrixMetricsStreamServlet");
 
        return bean;
    }
 
}

 

 

  

  

posted on   anpeiyong  阅读(245)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2020-08-04 Activiti---概述

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示