Hystrix

简介

主页:链接: https://github.com/Netflix/Hystrix/
在这里插入图片描述
Hystix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务,防止出现级联失败。

雪崩问题

微服务中,服务间的调用关系错综复杂,一个请求,可能要调用多个微服务才能实现,会形成非常复杂的调用链路:
在这里插入图片描述
如图所示,一次业务请求调用了A、H、I、P四个服务,这四个服务还可能去调用其他服务,若果这时,某个服务出现了异常。
在这里插入图片描述
如图,例如此时I服务出现了异常,请求阻塞,用户请求就不会得到响应,则tomcat的这个线程就不会释放,随后越来越多的请求到来,就会导致越来越多的请求阻塞:
在这里插入图片描述
服务器支持的线程和并发数有限,请求一直被阻塞,就会导致服务器资源被耗尽,从而导致其他服务都不可用,形成雪崩效应。

而Hystrix就可以有效地解决雪崩问题,Hystrix解决雪崩问题的手段主要包括:

  1. 线程隔离
  2. 服务降级

线程隔离

原理

线程隔离示意图:
在这里插入图片描述
解读:
Hystrix为每个依赖服务调用分配了一个小的线程池,当线程池已满调用将被立即拒绝,默认不使用排队,加速失败判定时间。
用户请求不再直接访问服务,而是通过线程池中的空闲线程访问,如果线程池已满或者请求超时,则会进行降级处理。

服务降级

服务降级:可以优先保证核心服务。
用户的请求故障时,不会被阻塞,更不会无休止地等待或者看到系统的崩溃,至少能看到一个执行结果(例如一条友好提示)。
服务降级虽然会导致请求失败,但是不会导致请求阻塞,而且最多影响这个依赖服务对应的线程池中的资源,对其他服务没有影响。
会触发Hystrix服务降级的情况:

  1. 线程池已满
  2. 请求超时

代码实现

服务降级:及时返回服务调用失败的结果,让线程不因为等待服务而阻塞。

1.引入依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2.开启熔断

在启动器类上添加注解:@EnableCircuitBreaker

package com.lt.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient //开启eureka客户端发现功能
@EnableCircuitBreaker //开启熔断器
//@SpringCloudApplication可用于替代上述三个注解
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

3.编写降级逻辑

当目标服务调用失败时,我们希望快速失败,给用户一个友好提示。因此需要提前编写好失败时的降级处理逻辑,要使用HystrixCommand来完成。
如下:

package com.lt.consumer.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
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;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/consumer")
@Slf4j
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/{id}")
    @HystrixCommand(fallbackMethod = "queryByIdFallBack")
    public String queryById(@PathVariable("id") Long id){
        if (id==2){
            throw new RuntimeException("太忙了");
        }
        String url = "http://user-server/user/"+id;
        return restTemplate.getForObject(url,String.class);
    }

    public String queryByIdFallback(Long id){
        log.error("查询用户信息失败.id:{}",id);
        return "对不起,网络太拥挤了";
    }

}

注意:

  1. 熔断的降级逻辑方法必须和正常逻辑方法保证有相同的参数列表和返回值声明。
  2. 由于要返回友好提示,所以一般返回值声明为String类型

说明:
@HystrixCommand(fallbackMethod = “queryByIdFallBack”):用来声明一个降级逻辑的方法
启动测试:
在这里插入图片描述
如图所示,当服务正常运行时,我们可以正常访问,当服务停机时,就会进行服务降级,返回友好提示。

4.默认的fallback

当有很多方式时,给每一个方法都添加fallback会显得非常麻烦,此时,我们就可以把fallback写在类上,实现默认的fallback。
代码如下:

package com.lt.consumer.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
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;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/consumer")
@Slf4j
@DefaultProperties(defaultFallback = "defaultFallback")
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/{id}")
    @HystrixCommand
    public String queryById(@PathVariable("id") Long id){
        if (id==2){
            throw new RuntimeException("太忙了");
        }
        String url = "http://user-server/user/"+id;
        return restTemplate.getForObject(url,String.class);
    }
    
    public String defaultFallback(){
        return "默认提示:对不起,网络太拥挤了!";
    }
}

注意:在类上指明统一的失败降级方法,那么该类中所有方法返回值类型都要与处理失败的方法返回值类型一致

5.超时设置

Hystrix的默认超时时长为1s,我们可以通过修改配置修改这个值,如下:

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 2000

注意单位是毫秒。
这个配置会作用于全局所有方法,此时只要当访问超时2s,就会触发服务降级,为了方便测试,可以给服务添加2s的睡眠时间来达到超时2s的目的。

Hystrix是一个开源的故障隔离和熔断库,它是由Netflix开发的,用于处理分布式系统中的服务请求。Hystrix的主要目标是提供一个安全的、有弹性的框架,帮助系统在面对服务不可用或过载时仍能保持运行,并提供有用的监控数据。以下是Hystrix设置的一些关键概念和配置: 1. **命令(Command)**:Hystrix将一个服务请求封装为一个“命令”,每个命令都有自己的线程池,当命令执行失败时,会触发回退策略。 2. **线程池(ThreadPool)**:为每个命令创建一个独立的线程池,用于异步执行命令。线程池的大小、超时等配置影响了服务的响应时间和容错能力。 3. **熔断器(Circuit Breaker)**:这是一个开关机制,当某个服务调用频繁失败或超时,熔断器会打开,阻止进一步的请求,直到状态恢复。 4. **超时(Timeout)**:可以设置每个命令的最大执行时间,防止无响应的服务阻塞整个请求链路。 5. **信号量(Semaphore)**:限制同一时间可以并发执行的命令数量,防止单点服务过载。 6. **缓存(Cache)**:Hystrix提供了基于Redis等缓存的请求结果存储,提高响应速度并降低后端压力。 7. **健康检查(Health Check)**:定期发送简单的请求来验证服务的健康状况,用于监控和显示服务的状态。 8. **仪表板(Dashboard)**:Hystrix提供了可视化工具,可以帮助监控和诊断命令的执行情况、失败率等。 相关问题-- 1. 如何在Hystrix中启用熔断器? 2. 如何配置Hystrix线程池的大小? 3. 如何使用Hystrix的健康检查功能? 4. Hystrix Dashboard如何接入到我的应用中? 5. Hystrix如何实现命令之间的依赖控制?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值