SpringCloud——Hystrix详解

目录

一、Hystrix介绍

1、分布式系统面临问题

2、Hystrix概念

3、Hystrix作用

(1)服务降级

(2)服务熔断

二、服务降级案例

1、搭建Eureka服务端

(1)创建maven工程

(2)导入依赖

(3)配置application.yml

(4)创建主启动类

(5)启动Eureka注册中心

2、搭建服务提供者Provider80

(1)创建maven工程

(2)导入依赖

(3)配置application.yml

(4)创建启动类

(5)创建controller(设置自身降级方法)

(6)测试自身降级

  3、搭建服务消费者Consumer83

(1)创建maven工程

(2)导入依赖

(3)配置application.yml

(4)创建主启动类

(5)创建远程调用服务接口

(6)创建controller

4、测试案例

 三、服务熔断

1、熔断设置参数

2、熔断类型

(1)熔断打开

(2)熔断关闭

(3)熔断半开


 

一、Hystrix介绍

1、分布式系统面临问题

        多个微服务之间调用的时候,假如微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务,这就是所谓的"扇出"。

        如果扇出的链路上某个微服务的调用响应的时间过长或者不可用,对微服A的调用就会占用越来越多的系统资源,进而引起系统崩溃,即"雪崩效应"。

        对于高流量的应用来说,单一的后端依赖可能会导致所有的服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。

        所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。

2、Hystrix概念

①Hystrix是一个用于处理分布式系统的延迟和容错的开源库,可以保证一个服务出现故障时,不会导致整个系统出现雪崩效应,以提高分布式系统弹性;

②作为“断路器”,在一个服务出现故障时,可以通过短路器监控,返回一个可以处理的响应结果,保证服务调用线程不会长时间被占用,避免故障蔓延。

3、Hystrix作用

(1)服务降级

服务出现故障时,给故障服务降级到事先准备好的故障处理结果,将此结果返回给服务消费者,如:

 

客户端访问服务1,服务1调用服务2,服务2出现故障,Hystrix服务降级,返回一个可以处理的结果给服务1,服务1再以友好的错误界面返回给客户端。

531f5d30feb74f85a8fb947901a5ab92.png

 

(2)服务熔断

熔断机制是应对服务雪崩的一种链路保护机制,当服务出现故障时,服务会进行降级,熔断该服务节点,迅速返回错误响应信息。当检测到服务访问正常时,恢复其链路节点。

86f7499c64794ece93e0ac1dc8275db9.png

 

二、服务降级案例

1、搭建Eureka服务端

(1)创建maven工程

ef9d8d6fd35e463fa53276c1eaff3587.png

 (2)导入依赖

导入Eureka服务端、web模块依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </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>
    </dependencies>

(3)配置application.yml

①服务端口为7001;

②Eureka服务端主机名;

③Eureka客户端:

register-with-eureka:是否在服务中心注册

fetchRegistry:是否可以在注册中心被发现

service-url:服务中心url地址

server:
  port: 7001

eureka:
  instance:
    hostname: localhost

  client:
    register-with-eureka: false
    fetchRegistry: false
    service-url:
      defaultZone: http://localhost:7001/eureka

(4)创建主启动类

@EnableEurekaServer:Eureka服务端注解

@SpringBootApplication
@EnableEurekaServer
public class Eureka7001 {
    public static void main(String[] args) {
        SpringApplication.run(Eureka7001.class,args);
    }
}

(5)启动Eureka注册中心

访问http://localhost:7001

78ca559626be4fbfbcb6b62d630f5d70.png

2、搭建服务提供者Provider80

(1)创建maven工程

73dae138417a427f9a7d28d39fa30ca0.png

 

(2)导入依赖

导入Eureka客户端、web模块、监控,Htstrix依赖

 <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>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
 </dependencies>

 (3)配置application.yml

①配置服务端口号为80;

②配置服务应用名称;

③配置Eureka注册中心,开启注册,指明注册中心地址。

server:
  port: 80

spring:
  application:
    name: provider

eureka:
  client:
    register-with-eureka: true
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

(4)创建启动类

@EnableEurekaClient:指明该服务为Eureka客户端

@EnableCircuitBreaker:开启Hystrix

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class Provider80 {
    public static void main(String[] args) {
        SpringApplication.run(Provider80.class,args);
    }
}

(5)创建controller(设置自身降级方法)

@HystriCommand注解:

fallbackMethod:指定服务降级后调用方法,降级方法参数一定要和controller方法参数一致

commandProperties:相关参数。

@RestController
public class FeignController {
    @Value("${server.port}")
    private String port;

    @GetMapping("/provider")
    public String hello(){
        return "访问端口号为:"+port;
    }

    @HystrixCommand(fallbackMethod = "TimeoutHandler",commandProperties = {
            //2秒钟以内就是正常的业务逻辑
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="2000")
    })
    @GetMapping("timeout")
    public String timeout(){
        try {
            //睡眠3秒
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello";
    }

    //降级后方法,上面方法出问题,我来处理,返回一个出错信息
    public String TimeoutHandler() {
        return "访问请求失败了,服务不可用";
    }
}

(6)测试自身降级

因为服务延迟3秒后执行,而降级设置时间为2秒,所以访问该请求时,服务降级

498c8a5210c34f869e892a907fddb09a.png

 测试完成后,为方便后边测试服务消费者降级,我们将服务提供者controller中时间设置为5秒以内业务为正常

@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000")

  3、搭建服务消费者Consumer83

(1)创建maven工程

da181a0a7f1c44899969df9c97d90959.png

 (2)导入依赖

引入OpenFeign、Eureka、web,服务监控,Hystrix依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </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>
  </dependencies>

(3)配置application.yml

①配置服务·端口号为83;

②配置服务名称为:Consumer83;

③配置Eureka客户端,开启注册。配置注册中心地址;

④开启Hystrix降级服务。

server:
  port: 83
spring:
  application:
    name: consumer83
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka  
feign:
  hystrix:
    enabled: true #如果处理自身的容错就开启。开启方式与生产端不一样。

(4)创建主启动类

开启Eureka客户端,远程条用Feign客户端,Hystrix服务

@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class Consumer83 {
    public static void main(String[] args) {
        SpringApplication.run(Consumer83.class,args);
    }
}

(5)创建远程调用服务接口

①@FeignClient注解,指定远程调用的服务名称,服务提供者Provider80、Provider81对应名称为:provider。

②接口中方法为:调用服务的controller方法。

@Component
@FeignClient(value = "PROVIDER")
public interface FeignService {
    //调用远程接口
    @GetMapping("/provider")
    public String hello();
}

(6)创建controller

远程调用服务时间超过1.5秒就会自动降级。

@RestController
public class FeignController {
    //调用远程服务接口
    @Autowired
    private FeignService feignService;

    @GetMapping("consumer")
    public String hello(){
        //调用接口
        return feignService.hello();
    }

    //超时降级演示
    @HystrixCommand(fallbackMethod = "TimeoutHandler",commandProperties = {
            //超过1.5秒就降级自己
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
    })
    @GetMapping("time")
    public String time(){
        return feignService.timeout();
    }
    
    //降级方法
    public String TimeoutHandler(){
        return "远程调用服务超时,调用失败";
    }
}

4、测试案例

①启动Eureka7001

②启动Provider80

③启动·Consumer83

④访问http://localhost:83/time

由于远程服务需要3秒后才能处理结果,而设置超时时间为1.5秒,所以服务消费者自动调用降级后的方法。

ce240a3668ba49c2bd2d4d8669afa3c0.png 

 三、服务熔断

1、熔断设置参数

①circuitBreaker.enabled:是否开启熔断;

②circuitBreaker.requestVolumeThreshold:当前服务失败几次后开启断路,默认20次;

③circuitBreaker.sleepWindowInMilliseconds:设置断路时间,过了该时间后会尝试恢复,在断路时间内,即使请求正确也会走降级方法;

2、熔断类型

(1)熔断打开

熔断打开后,在此时间内不会对该服务进行调用,而是直接访问降级方法。通过设置熔断时间,当达到该时间后,会尝试恢复该服务。

(2)熔断关闭

熔断关闭代表服务正常,不会干扰正常服务调用。

(3)熔断半开

熔断半开时,请求可以访问服务,若请求正常访问,则熔断会关闭;若请请求不正常,继续熔断,调用降级方法。

 

 

04-26
### Hystrix微服务架构中的作用与使用方式 #### 1. Hystrix 的核心作用 Hystrix 是一个用于处理分布式系统中延迟和故障的库,旨在保护微服务架构免受级联失败的影响。它的主要功能包括以下几个方面: - **熔断机制**:当某个服务调用频繁失败时,Hystrix 可以暂时切断对该服务的调用,从而避免继续尝试不可靠的操作并节省资源[^2]。 - **降级处理**:如果被调用的服务发生异常或超时,Hystrix 能够执行预先定义好的回退逻辑(Fallback Logic),确保即使某些组件失效,整体系统仍可维持基本功能[^3]。 - **线程池隔离**:为了减少单一服务故障对其他模块造成连锁反应的可能性,Hystrix 将每个依赖项分配到独立的线程池里运行。这样即便某一部分耗尽了自己的配额也不会波及其他部分。 #### 2. 使用 Hystrix 的典型场景 假设存在三个依次关联的服务 A → B → C 。一旦最末端的服务 C 出现问题未能及时响应,则中间层 B 和顶层 A 都会被迫等待直至超时才返回错误消息给最终用户。在此期间它们各自持有的连接处于挂起状态无法再服务于新的请求。随着未决事务数量累积增多,很可能引发所谓的“雪崩效应”,即整个链条上的所有节点都被拖垮停止运作[^4]。 此时引入 Hystrix 后便可以有效缓解此类危机状况的发生概率及其严重程度。例如设定合理的超时期限以及最大重试次数等参数控制;同时制定相应的 fallback 方法,在检测到目标主机无应答之后立即切换至备用流程而非一味死磕原路径直到彻底卡住为止。 #### 3. 如何在 Java 应用程序中使用 Hystrix? 下面给出一段简单的代码片段展示如何利用 Spring Boot 来集成 Hystrix 并实现基础的功能支持: ```java @RestController public class ExampleController { @GetMapping("/example") @HystrixCommand(fallbackMethod = "fallbackExample") //指定回滚方法名 public String example() throws InterruptedException{ boolean shouldFail = new Random().nextBoolean(); if(shouldFail){ Thread.sleep(5000); //模拟长时间操作导致超时 throw new RuntimeException("Operation failed"); } return "Success"; } private String fallbackExample(){ return "Fallback response"; } } ``` 在这个例子当中我们创建了一个名为 `example` 的 RESTful 接口并通过注解形式将其标记为受 Hystrix 控制的对象。每当触发该 endpoint 请求的时候都会先判断随机产生的布尔值是否成立进而决定下一步动作——要么顺利完成任务反馈成功信息;要么人为制造障碍使得过程被迫中断转而激活事先准备完毕的安全措施也就是这里的 fallbackExample 函数体内容。 --- ###
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swttws.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值