• SpringCloud-Hystrix


    一、介绍

    (1)避免单个服务出现故障导致整个应用崩溃。
    (2)服务降级:服务超时、服务异常、服务宕机时,执行定义好的方法。(做别的)
    (3)服务熔断:达到熔断条件时,服务禁止被访问,执行定义好的方法。(不做了)
    (4)服务限流:高并发场景下的一大波流量过来时,让其排队访问。(排队做)

    二、构建项目

    (1)pom.xml

    <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>com.wsh.springcloud</groupId>
                <artifactId>cloud-api-common</artifactId>
                <version>1.0-SNAPSHOT</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.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    • 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

    (2)编写application.yml文件

    server:
      port: 8001
    
    spring:
      application:
        name: cloud-provider-hystrix-payment
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: org.gjt.mm.mysql.Driver
        url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
        username: root
        password: wsh666
    
    eureka:
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
          defaultZone: http://eureka1.com:7001/eureka
        instance:
          instance-id: hystrixPayment8001
          prefer-ip-address: true
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    (3)启动类PaymentHystrixMain8001

    package com.wsh.springcloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    /**
     * @ClassName PaymentHystrixMain8001
     * @Description: TODO
     * @Author wshaha
     * @Date 2023/10/14
     * @Version V1.0
     **/
    @SpringBootApplication
    @EnableEurekaClient
    public class PaymentHystrixMain8001 {
    
        public static void main(String[] args) {
            SpringApplication.run(PaymentHystrixMain8001.class, args);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    (4)编写PaymentService

    package com.wsh.springcloud.service;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    /**
     * @ClassName PaymentService
     * @Description: TODO
     * @Author wshaha
     * @Date 2023/10/14
     * @Version V1.0
     **/
    @Service
    @Slf4j
    public class PaymentService {
    
        public String test1(Integer id){
            return "test1: " + Thread.currentThread().getName() + " " + id;
        }
    
        public String test2(Integer id){
            try {
                Thread.sleep(3000);
            } catch (Exception e){
    
            }
            return "test2: " + Thread.currentThread().getName() + " " + id;
        }
    }
    
    
    • 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

    (5)编写PaymentController

    package com.wsh.springcloud.controller;
    
    import com.wsh.springcloud.service.PaymentService;
    import lombok.extern.slf4j.Slf4j;
    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.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @ClassName PaymentController
     * @Description: TODO
     * @Author wshaha
     * @Date 2023/10/14
     * @Version V1.0
     **/
    @Slf4j
    @RequestMapping("/payment")
    @RestController
    public class PaymentController {
    
        @Autowired
        private PaymentService paymentService;
    
        @GetMapping("/test1/{id}")
        public String test1(@PathVariable("id") Integer id){
            return paymentService.test1(id);
        }
    
        @GetMapping("/test2/{id}")
        public String test2(@PathVariable("id") Integer id){
            return paymentService.test2(id);
        }
    }
    
    
    • 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

    (6)运行
    在这里插入图片描述

    三、 服务降级配置

    (1)方式一(一旦方法出现异常或超时了,会调用@HystrixCommand的降级方法)

    注:@EnableCircuitBreaker用于启动断路器,支持多种断路器,@EnableHystrix用于启动断路器,只支持Hystrix断路器

    a、PaymentService编写降级方法,配置注解@HystrixCommand

    @Service
    @Slf4j
    public class PaymentService {
    
        public String test1(Integer id){
            return "test1: " + Thread.currentThread().getName() + " " + id;
        }
    
        @HystrixCommand(fallbackMethod = "test2fallback", commandProperties = {
                @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
        })
        public String test2(Integer id){
            try {
                Thread.sleep(3000);
            } catch (Exception e){
    
            }
            return "test2: " + Thread.currentThread().getName() + " " + id;
        }
        public String test2fallback(Integer id){
            return "test2fallback: " + id;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    b、启动类开启断路器

    @SpringBootApplication
    @EnableEurekaClient
    @EnableCircuitBreaker
    public class PaymentHystrixMain8001 {
    
        public static void main(String[] args) {
            SpringApplication.run(PaymentHystrixMain8001.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    c、运行
    在这里插入图片描述
    (2)方式二(配置全局使用的降级方法)
    a、使用@DefaultProperties,注意全局降级方法的参数列表为空

    @Slf4j
    @RequestMapping("/payment")
    @RestController
    @DefaultProperties(defaultFallback = "defaultFallbacktest")
    public class PaymentController {
    
        @Autowired
        private PaymentService paymentService;
    
        @GetMapping("/test1/{id}")
        public String test1(@PathVariable("id") Integer id){
            return paymentService.test1(id);
        }
    
        @GetMapping("/test2/{id}")
        @HystrixCommand
        public String test2(@PathVariable("id") Integer id){
            return paymentService.test2(id);
        }
        public String defaultFallbacktest(){
            return "defaultFallbacktest";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    b、编写PaymentService

    @Service
    @Slf4j
    public class PaymentService {
    
        public String test1(Integer id){
            return "test1: " + Thread.currentThread().getName() + " " + id;
        }
    
    //    @HystrixCommand(fallbackMethod = "test2fallback", commandProperties = {
    //            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    //    })
        public String test2(Integer id){
    //        try {
    //            Thread.sleep(3000);
    //        } catch (Exception e){
    //
    //        }
            int i = 1 / 0;
            return "test2: " + Thread.currentThread().getName() + " " + id;
        }
    //    public String test2fallback(Integer id){
    //        return "test2fallback: " + id;
    //    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    c、运行
    在这里插入图片描述
    (3)方式三,feign调用其他服务时,可以利用实现类对应降级方法
    a、pom.xml增加依赖

    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    b、application.yml增加

    feign:
      hystrix:
        enabled: true
    
    • 1
    • 2
    • 3

    c、编写远程调用接口FeignTestService

    @Component
    @FeignClient(value = "CLOUD-PAYMENT-SERVICE", fallback = FeignTestServiceImpl.class)
    public interface FeignTestService {
    
        @GetMapping("/payment/test")
        public CommonResult<String> test();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    d、编写降级方法类FeignTestServiceImpl

    @Component
    public class FeignTestServiceImpl implements FeignTestService{
    
        @Override
        public CommonResult<String> test() {
            return new CommonResult(444, "", "error");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    e、编写Controller

    @Slf4j
    @RequestMapping("/payment")
    @RestController
    //@DefaultProperties(defaultFallback = "defaultFallbacktest")
    public class PaymentController {
    
        @Autowired
        private PaymentService paymentService;
    
        @Autowired
        private FeignTestService feignTestService;
    
        @GetMapping("/test1/{id}")
        public String test1(@PathVariable("id") Integer id){
            return paymentService.test1(id);
        }
    
        @GetMapping("/test2/{id}")
    //    @HystrixCommand
        public String test2(@PathVariable("id") Integer id){
            return paymentService.test2(id);
        }
    //    public String defaultFallbacktest(){
    //        return "defaultFallbacktest";
    //    }
    
        @GetMapping("/test")
        public CommonResult<String> test(){
            return feignTestService.test();
        }
    }
    
    • 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

    f、运行
    在这里插入图片描述

    四、服务熔断配置

    (1)服务先降级,然后熔断,后面尝试恢复
    (2)在规定时间内,接口访问量超过设置阈值,并且失败率大于等于设置阈值
    (3)例子

    @Service
    @Slf4j
    public class PaymentService {
    
        @HystrixCommand(fallbackMethod = "test1fallback", commandProperties = {
                @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),//开启断路器
                @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//请求次数阈值
                @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),//规定时间内
                @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")//失败率阈值
        })
        public String test1(Integer id){
            int i = 1 / id;
            return "test1: " + Thread.currentThread().getName() + " " + id;
        }
        public String test1fallback(Integer id){
            return "test1fallback: " + id;
        }
    
    //    @HystrixCommand(fallbackMethod = "test2fallback", commandProperties = {
    //            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    //    })
        public String test2(Integer id){
    //        try {
    //            Thread.sleep(3000);
    //        } catch (Exception e){
    //
    //        }
            int i = 1 / 0;
            return "test2: " + Thread.currentThread().getName() + " " + id;
        }
    //    public String test2fallback(Integer id){
    //        return "test2fallback: " + id;
    //    }
    }
    
    • 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

    五、监控界面搭建(只能监控hystrix接管的方法)

    (1)编写pom.xml

    <?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>demo20220821</artifactId>
            <groupId>com.wsh.springcloud</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>cloud-consumer-hystrix-dashboard9001</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            </dependency>
            <dependency>
                <groupId>com.wsh.springcloud</groupId>
                <artifactId>cloud-api-common</artifactId>
                <version>1.0-SNAPSHOT</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.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </project>
    
    • 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

    (2)编写application.yml

    server:
      port: 9001
    
    spring:
      application:
        name: cloud-hystrix-dashboard
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (3)编写启动类

    package com.wsh.springcloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
    
    /**
     * @ClassName HystrixDashboardMain9001
     * @Description: TODO
     * @Author wshaha
     * @Date 2023/10/14
     * @Version V1.0
     **/
    @SpringBootApplication
    @EnableHystrixDashboard
    public class HystrixDashboardMain9001 {
        public static void main(String[] args) {
            SpringApplication.run(HystrixDashboardMain9001.class, args);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    (4)运行
    在这里插入图片描述
    (5)配置被监控的项目
    a、pom.xml

    加上探针spring-boot-starter-actuator
    
    • 1

    b、启动类加上

    package com.wsh.springcloud;
    
    import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    import org.springframework.context.annotation.Bean;
    
    /**
     * @ClassName PaymentHystrixMain8001
     * @Description: TODO
     * @Author wshaha
     * @Date 2023/10/14
     * @Version V1.0
     **/
    @SpringBootApplication
    @EnableEurekaClient
    @EnableCircuitBreaker
    @EnableFeignClients
    public class PaymentHystrixMain8001 {
    
        public static void main(String[] args) {
            SpringApplication.run(PaymentHystrixMain8001.class, args);
        }
    
        @Bean
        public ServletRegistrationBean getServlet(){
            HystrixMetricsStreamServlet hystrixMetricsStreamServlet = new HystrixMetricsStreamServlet();
            ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(hystrixMetricsStreamServlet);
            servletRegistrationBean.setLoadOnStartup(1);
            servletRegistrationBean.addUrlMappings("/hystrix.stream");
            servletRegistrationBean.setName("HystrixMetricsStreamServlet");
            return servletRegistrationBean;
        }
    }
    
    
    • 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

    (6)监控界面
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    MDM授权管理设计方案
    leetcode:2926. 平衡子序列的最大和 【树状数组维护最大前缀和】
    基于Java Swing和BouncyCastle的证书生成工具
    数据结构第四课 -----线性表之队列
    内地学生可以参加香港高考吗?3分钟教你走捷径拿香港身份远离内卷攻略!
    Python算法图解——递归(一):打印从1循环到10
    主要控制系统之间的逻辑关系
    如何批量压缩图片大小?教你3个批量压缩图片的方法
    Chrome中如何导出和导入书签
    【第94题】JAVA高级技术-网络编程13(简易聊天室8:使用Socket传递图片)
  • 原文地址:https://blog.csdn.net/qq_25243147/article/details/133828791