Hystrix服务降级

一、了解服务雪崩

  分布式系统面临多个微服务之间调用的时候,假设A调用B和C,B和C有调用其它微服务,这就是所谓的“扇出”,如果扇出链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,从而引起系统崩溃,这就是所谓的“雪崩效应”。

  对于高流量的应用来说,单一的后端依赖可能会导致所有的服务器上的所有的资源都在几秒钟饱和,比失败更糟糕的是这些应用程序还可能导致服务之间的延迟增加,备份队列、线程和其他系统资源紧张,导致整个系统发生更多的级联故障,这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统,所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块还会依然接收流量,然后这个有个问题的模块还调用了其他模块,这样就会发生级联故障或者叫做雪崩。

二、Hystrix是什么

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

“断路器”本身是一种开关装置,当某个服务单元发生故障后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的现成不会被长时间的、不必要的占用,从而避免了故障在分布式系统中的蔓延直至雪崩。

三、服务降级(fallback)

  假设对方系统不可用,需要提供一个兜底的备选方案,不要让调用方一直等待。比如:“服务器忙,请稍后再试。” 处理这样的方式就是服务降级。

  服务降级一般会在客户端进行处理,方便演示我们会在服务端和客户端都进行服务降级处理。

哪些情况会触发降级

(1)程序运行异常

(2)超时

(3)服务熔断触发服务降级

(4)线程池/信号量打满也会导致服务降级

四、代码篇

1.全局pom

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 
  3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5   <modelVersion>4.0.0</modelVersion>
  6 
  7   <groupId>com.seegot.springcloud</groupId>
  8   <artifactId>cloud2020</artifactId>
  9   <version>1.0-SNAPSHOT</version>
 10   <modules> 
 11     <module>cloud-eureka-server7001</module>  
 12       <module>cloud-provider-hystrix-payment8001</module>
 13       <module>cloud-consumer-feign-hystrix-order80</module>
 14   </modules>
 15   <packaging>pom</packaging>
 16 
 17   <!--统一管理jar包版本-->
 18   <properties>
 19     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 20     <maven.compiler.source>1.8</maven.compiler.source>
 21     <maven.compiler.target>1.8</maven.compiler.target>
 22     <junit.version>4.12</junit.version>
 23     <log4j.version>1.2.17</log4j.version>
 24     <lombok.version>1.16.18</lombok.version>
 25     <mysql.version>5.1.47</mysql.version>
 26     <druid.version>1.1.16</druid.version>
 27     <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
 28   </properties>
 29 
 30 
 31   <!--子模块继承之后,提供作用:锁定版本+子modlue不用谢groupId和version-->
 32   <dependencyManagement>
 33     <dependencies>
 34       <!--springboot 2.2.7-->
 35       <dependency>
 36         <groupId>org.springframework.boot</groupId>
 37         <artifactId>spring-boot-dependencies</artifactId>
 38         <version>2.2.7.RELEASE</version>
 39         <type>pom</type>
 40         <scope>import</scope>
 41       </dependency>
 42       <!--spring cloud Hoxton.SR5-->
 43       <dependency>
 44         <groupId>org.springframework.cloud</groupId>
 45         <artifactId>spring-cloud-dependencies</artifactId>
 46         <version>Hoxton.SR5</version>
 47         <type>pom</type>
 48         <scope>import</scope>
 49       </dependency>
 50       <!--spring cloud alibaba 2.1.0.RELEASE-->
 51       <dependency>
 52         <groupId>com.alibaba.cloud</groupId>
 53         <artifactId>spring-cloud-alibaba-dependencies</artifactId>
 54         <version>2.1.0.RELEASE</version>
 55         <type>pom</type>
 56         <scope>import</scope>
 57       </dependency>
 58       <!--mysql-->
 59       <dependency>
 60         <groupId>mysql</groupId>
 61         <artifactId>mysql-connector-java</artifactId>
 62         <version>${mysql.version}</version>
 63       </dependency>
 64       <!--druid-->
 65       <dependency>
 66         <groupId>com.alibaba</groupId>
 67         <artifactId>druid</artifactId>
 68         <version>${druid.version}</version>
 69       </dependency>
 70       <!--mybatis-->
 71       <dependency>
 72         <groupId>org.mybatis.spring.boot</groupId>
 73         <artifactId>mybatis-spring-boot-starter</artifactId>
 74         <version>${mybatis.spring.boot.version}</version>
 75       </dependency>
 76       <dependency>
 77         <groupId>org.projectlombok</groupId>
 78         <artifactId>lombok</artifactId>
 79       </dependency>
 80     </dependencies>
 81   </dependencyManagement>
 82 
 83   <build>
 84     <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
 85       <plugins>
 86         <plugin>
 87           <artifactId>maven-clean-plugin</artifactId>
 88           <version>3.1.0</version>
 89         </plugin>
 90         <plugin>
 91           <artifactId>maven-site-plugin</artifactId>
 92           <version>3.7.1</version>
 93         </plugin>
 94         <plugin>
 95           <artifactId>maven-project-info-reports-plugin</artifactId>
 96           <version>3.0.0</version>
 97         </plugin>
 98       </plugins>
 99     </pluginManagement>
100     <plugins>
101       <plugin>
102         <groupId>org.apache.maven.plugins</groupId>
103         <artifactId>maven-site-plugin</artifactId>
104         <configuration>
105           <locales>en,fr</locales>
106         </configuration>
107       </plugin>
108       <!--热启动插件-->
109       <plugin>
110         <groupId>org.springframework.boot</groupId>
111         <artifactId>spring-boot-maven-plugin</artifactId>
112         <configuration>
113           <fork>true</fork>
114           <addResources>true</addResources>
115         </configuration>
116       </plugin>
117     </plugins>
118   </build>
119   <repositories>
120     <repository>
121       <id>nexus-aliyun</id>
122       <name>Nexus aliyun</name>
123       <url>http://maven.aliyun.com/nexus/content/groups/public</url>
124       <releases>
125         <enabled>true</enabled>
126       </releases>
127       <snapshots>
128         <enabled>false</enabled>
129       </snapshots>
130     </repository>
131   </repositories>
132 </project>
View Code

2.新建eureka-server7001

(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>cloud2020</artifactId>
        <groupId>com.seegot.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-server2001</artifactId>

    <dependencies>
        <!--eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!--引入自己定义的api通用包,可以使用payment支付的entity-->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</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>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

(2)新建application.yml

server:
  port: 7001

# eureka配置
eureka:
  instance:
    hostname: eureka7001.com #eureka服务端的实例名称
  client:
    # false表示不想注册中心注册自己
    register-with-eureka: false
    # false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要检索服务
    fetch-registry: false
    service-url:
      # 设置Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
      #defaultZone: http://eureka7002.com:7002/eureka/
      # 单机就是7001自己守望自己
      defaultZone: http://eureka7001.com:7001/eureka/
  server:
    enable-self-preservation: false # 禁用自我保护模式
    eviction-interval-timer-in-ms: 2000

(3)修改主入口类

package com.seegot.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @program: cloud2020
 * @description:
 * @author: PP Zhang
 * @create: 2020-06-09 22:15
 */
@SpringBootApplication
@EnableEurekaServer // 表示自己就是注册中心
public class EurekaMain7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMain7001.class,args);
    }
}

(4)测试(第一次时Application下面时没有任何内容的,由于我这边起着服务,所以会有一条记录)

如果能访问到下面页面说明,eureka配置成功。

 

3.新建服务生产者cloud-provider-hystrix-payment8001的module

(1)编写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>cloud2020</artifactId>
        <groupId>com.seegot.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-hystrix-payment8001</artifactId>


    <dependencies>
        <!--注入hystrix依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <!--引入自己定义的api通用包,可以使用payment支付的entity-->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--web-->
        <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>
        <!--免写get set等-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <!--测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--注入eureka client 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>

(2)新建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,http://eureka7002.com:7002/eureka # 如果用集群,开启它
      defaultZone: http://eureka7001.com:7001/eureka # 单机

(3)新建业务service,我们在impl中测试了服务降级,一般不会在服务端进行服务降级而是在客户端进行服务降级。

package com.seegot.springcloud.service;

/**
 * @program: cloud2020
 * @description:
 * @author: PP Zhang
 * @create: 2020-06-15 15:30
 */
public interface PaymentService {
    public String paymentInfo_OK(Integer id);
    public String paymentInfo_TimeOut(Integer id);
}
package com.seegot.springcloud.service.impl;

import com.seegot.springcloud.service.PaymentService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @program: cloud2020
 * @description:
 * @author: PP Zhang
 * @create: 2020-06-15 15:31
 */
@Service
public class PaymentServiceImpl implements PaymentService {
    /**
    * @Description: 正常访问
    * @Param:
    * @return:
    * @Author: PP Zhang
    * @Date: 2020/6/15
    */
    @Override
    public String paymentInfo_OK(Integer id) {
        return "线程池" + Thread.currentThread().getName() + "paymentInfo_OK,id "+"	"+"!!!!";
    }
    // 一旦服务调用方法失败并抛出异常错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中指定的方法
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000") // 当前方法5秒以内走正常业务逻辑,超时进行兜底
    }) // 意思当前方法出问题(访问超时等),那么由paymentInfo_TimeOutHandler方法进行兜底处理。
    @Override
    public String paymentInfo_TimeOut(Integer id) {
        // int a = 10/0;
        int timeNum = 3;
        try {
            TimeUnit.SECONDS.sleep(timeNum);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        return "线程池" + Thread.currentThread().getName() + "paymentInfo_TimeOut,id "+"	"+"!!!! 耗时"+timeNum+"秒钟";
    }
    public String paymentInfo_TimeOutHandler(Integer id){
        return "线程池" + Thread.currentThread().getName() + "paymentInfo_TimeOutHandler,id "+"	"+"!~~~~(>_<)~~~~";
    }
}

(4)新建controller

package com.seegot.springcloud.controller;

import com.seegot.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @program: cloud2020
 * @description:
 * @author: PP Zhang
 * @create: 2020-06-15 15:47
 */
@RestController
@Slf4j
public class PaymentController {
    @Resource
    private PaymentService paymentService;
    @Value("${server.port}")
    private String serverPort;
    /** 
    * @Description: 模拟正常的业务流程
    * @Param:  
    * @return:  
    * @Author: PP Zhang
    * @Date: 2020/6/15 
    */
    @GetMapping(value = "/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id) {
        String result = paymentService.paymentInfo_OK(id);
        log.info("****result"+ result);
        return  result;
    }
    /** 
    * @Description: 模拟复杂的业务流程 
    * @Param:  
    * @return:  
    * @Author: PP Zhang
    * @Date: 2020/6/15 
    */
    @GetMapping(value = "/payment/hystrix/timeout/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id) {
        String result = paymentService.paymentInfo_TimeOut(id);
        log.info("****result"+ result);
        return  result;
    }
}

(5)修改主程序入口

package com.seegot.springcloud;

        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
        import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @program: cloud2020
 * @description:
 * @author: PP Zhang
 * @create: 2020-06-15 15:29
 */
@SpringBootApplication
@EnableEurekaClient // 开启eurek
@EnableCircuitBreaker // 回路
public class PaymentHystrixMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrixMain8001.class,args);
    }
}

4.客户端进行服务消费及服务降级处理。新建cloud-sonsumer-feign-hystrix-order80

(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>cloud2020</artifactId>
        <groupId>com.seegot.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-sonsumer-feign-hystrix-order80</artifactId>
    <dependencies>
        <!--引入openfeign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--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>
        <!--引入自己定义的api通用包,可以使用payment支付的entity-->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</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>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

(2)新建application.yml

server:
  port: 80
eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/
feign:
  hystrix:
    enabled: true

(3)新建service,重点需要注意@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class) // 通过Feign调用的哪个微服务上的方法。

前者指定服务,后者指定全局兜底类。

package com.seegot.springcloud.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * @program: cloud2020
 * @description:
 * @author: PP Zhang
 * @create: 2020-06-16 21:21
 */
@Component // 能被扫描
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class) // 通过Feign调用的哪个微服务上的方法。
public interface PaymentHystrixService {
    // 直接调用的时8001Controller中的同样的方法
    @GetMapping(value = "/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id);
    @GetMapping(value = "/payment/hystrix/timeout/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id);

}

(4)新建PaymentHystrixService的实现接口,这里的目的是当调用CLOUD-PROVIDER-HYSTRIX-PAYMENT服务下的方法时,如果发生异常,那么可以通过这种方法实现异常兜底,而且是全局兜底,不需要单个指定,异常兜底方法。

package com.seegot.springcloud.service;

import org.springframework.stereotype.Component;

/**
 * @program: cloud2020
 * @description:
 * @author: PP Zhang
 * @create: 2020-06-17 11:05
 */
@Component
public class PaymentFallbackService implements PaymentHystrixService {
    @Override
    public String paymentInfo_OK(Integer id) {
        return  "----------PaymentFallbackService fall back-paymentInfo_OK o(∩_∩)o 哈哈";
    }

    @Override
    public String paymentInfo_TimeOut(Integer id) {
        return "----------PaymentFallbackService fall back-paymentInfo_TimeOut,~~~~(>_<)~~~~";
    }
}

(5)controller

1.当方法上无@HystrixCommand修饰,那么当该方法在调用CLOUD-PROVIDER-HYSTRIX-PAYMENT下的服务出现异常,则会通过 PaymentFallbackService 进行异常处理。

2.当方法上有@HystrixCommand修饰且指定了具体异常处理方法,那么按照指定异常处理。这个属于独享处理。一般属于类内处理。

如: @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") })

3.当方法上有@HystrixCommand,但未指定具体异常处理方法,同时呢,类上又有@DefaultProperties(defaultFallback = "payment_Global_Fallback") // 统一跳转到统一的处理页面。

进行修饰,那么当方法出现异常时,通过类上指定的方法进行处理。一般属于类内处理。

package com.seegot.springcloud.controller;

import com.seegot.springcloud.entites.CommonResult;
import com.seegot.springcloud.entites.Payment;
import com.seegot.springcloud.service.PaymentHystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @program: cloud2020
 * @description:
 * @author: PP Zhang
 * @create: 2020-06-16 21:24
 */
@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_Fallback") // 统一跳转到统一的处理页面。
public class OrderHystrixController {
    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping(value = "/consumer/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id){
        String result = paymentHystrixService.paymentInfo_OK(id);
        return  result;
    }
    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") // 当前方法1.5秒以内走正常业务逻辑,超时进行兜底
    }) // 意思当前方法出问题(访问超时等),那么由paymentInfo_TimeOutHandler方法进行兜底处理。
    @GetMapping(value = "/consumer/payment/hystrix/timeout/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
        String result = paymentHystrixService.paymentInfo_TimeOut(id);
        return result;
    }
    @HystrixCommand // 没有特别指明异常处理方法,那么就是用全局@DefaultProperties 指定的错误异常处理方法。
    @GetMapping(value = "/consumer/payment/hystrix/timeout2/{id}")
    public String paymentInfo_TimeOut2(@PathVariable("id") Integer id){
        String result = paymentHystrixService.paymentInfo_TimeOut(id);
        return result;
    }
    // 独享的错误、异常处理
    public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){
        return "我是消费者80,对方支付系统繁忙请等待10秒钟后再试或者自己运行错误,请检查自己~~~~(>_<)~~~~";
    }
    // 全局的错误、异常处理
    public String payment_Global_Fallback(){
        return "我是消费者80,全局异常处理信息,请检查自己~~~~(>_<)~~~~";
    }
}

(6)主入口  @EnableFeignClients @EnableHystrix

package com.seegot.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @program: cloud2020
 * @description:
 * @author: PP Zhang
 * @create: 2020-06-16 21:19
 */
@SpringBootApplication
@EnableFeignClients // 激活feign
@EnableHystrix
public class OrderHystrixMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderHystrixMain80.class,args);
    }
}

 

原文地址:https://www.cnblogs.com/pengpengzhang/p/13152117.html