SpringCloud学习-Hystrix

1 引言

主要是为了解决服务的雪崩问题,即一个服务出错,引起多个相关的服务无法正常运行。

  • 降级机制:当某一个服务出现超时、资源不足、出现异常时,可以执行一个降级方法,直接返回一个托底数据。
  • 服务隔离:提供了一个Hystrix线程池,信号量,和服务的线程池相互隔离。
  • 熔断:当某一个服务失败率打到一个阈值时,自动触发降级机制。
  • 缓存:能够缓存请求的信息。

2 降级机制的实现

1、导入依赖

<dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-hystrixartifactId>
        dependency>

2、在启动类上添加注解

@EnableCircuitBreaker

3、针对接口编写降级方法

    //降级方法,可自定义
    public Customer findByIdFallback(Integer id) {
        return new Customer(-1,"",0);
    }

    @GetMapping("/customer/{id}")
    @HystrixCommand(fallbackMethod = "findByIdFallback")
    public Customer findById(@PathVariable(value = "id") Integer id) {
        int i = 1 / 0;
        return searchClient.findById(id);
    }

4、在被调用的方法上添加注解

@HystrixCommand(fallbackMethod = "findByIdFallback")

3 线程隔离

如果使用服务的线程池取接收用户的请求,并使用当前线程去执行调用其他服务的功能,如果其他服务出现了故障,导致该服务的线程大量堆积,导致该服务无法处理其他业务的功能。

1、Hystrix的线程池(默认的配置),接收用户请求时,会使用服务的线程池,执行业务代码,调用其他服务时,采用Hystrix的线程池。

2、信号量,使用的还是服务的线程池,但是能够帮助管理线程池,避免线程大量堆积,无法处理新请求的问题。

4 线程池的配置

具体的配置name属性需要去查看HystrixCommandProperties类

1、线程隔离的策略:

name=hystrix.command.default.execution.isolation.strateg, value=THREAD, SEMAPHORE

2、指定超时时间(只针对线程池):name=hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds, value=1000

3、是否开启超时时间配置:

name=hystrix.command.default.execution.timeout.enable, value=true

4、超时之后是否中断线程:name=hystrix.command.default.execution.isolation.thread.interruptOnTimeout, value=true

5、取消之后是否中断:

name=hystrix.command.default.execution.isolation.thread.interruptOnCancel, value=false

5 信号量的配置信息

1、指定信号量的最大并发请求书

name=hystrix.command.default.execution.isolation.semaphore.maxConcurrenRequests, value=10

2、线程隔离的策略:

name=hystrix.command.default.execution.isolation.strateg, value=THREAD, SEMAPHORE

6 Hystrix的断路器(熔断机制)

在调用指定服务时,如果失败率达到了输入的一个阈值,将断路器从Closed的状态转变为Open状态。此时指定服务无法被访问,如果被访问,会执行fallback方法。在一定时间内,会再次转变为half open状态,允许一个请求发送到我的指定服务,如果成功,转变为closed,如果失败,服务会再次转变为open状态,会再次循环上述过程,直到变为closed状态。

配置断路器的监控界面

1、导入依赖

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

2、在启动类添加注解

@EnableHystrixDashboard

3、配置一个servlet路径,指定上Hystrix的servlet

@WebServlet("/hystrix.stream")
public class HystrixServlet extends HystrixMetricsStreamServlet {
}
//在启动类上,添加扫描Servlet的注解
@ServletComponentScan("com.arivan.servlet")

5、使用

直接访问映射好的Servlet的路径

配置断路器的属性

1、断路器的开关:name=hystrix.command.default.circuitBreaker.enable, value=true

2、失败阈值的总请求数:

name=hystrix.command.default.circuitBreaker.requestVolumeThreshold, value=20

3、请求总数失败率:

name=hystrix.command.default.circuitBreaker.errorThresholdPercentage, value=50

4、断路器open状态后,多少秒是拒绝请求的:

name=hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds, value=5000

5、强制让服务拒绝请求:

name=hystrix.command.default.circuitBreaker.forceOpen, value=false

6、强制服务接收请求(与5互斥):

name=hystrix.command.default.circuitBreaker.forceClose, value=false

具体配置:

@GetMapping("/customer/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback", commandProperties = {
     @HystrixProperty(name = "execution.isolation.strategy",value = "SEMAPHORE"),
     @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
})

7 请求缓存

1、请求缓存的生命周期是一次请求。

2、请求缓存时缓存当前线程中的一个方法,将方法的返回结果作为value。

3、在一次请求中,目标方法被调用过一次以后,都会被缓存。

请求缓存的实现

1、创建一个service,并在service中调用search服务

@Service
public class CustomerService {

    @Autowired
    private SearchClient searchClient;

    @CacheResult
    @HystrixCommand(commandKey = "findById")
    public Customer findById(@CacheKey Integer id) throws InterruptedException {
        return searchClient.findById(id);
    }

    @CacheRemove(commandKey = "findById")
    @HystrixCommand
    public void clearFindById(@CacheKey Integer id) {
        System.out.println("findById缓存被清空");
    }
}

2、使用请求缓存的注解

@CacheResult //帮助缓存当前方法的返回结果(需要和@HystrixCommand配合使用)
@CacheRemove //帮助清除某一个缓存信息(基于CommandKey)
@CacheKey  //指定方法中的哪个参数作为缓存的key

3、编写Filter,去构建HystrixRequestContext

@WebFilter("/*")
public class HystrixRequestContextInitFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HystrixRequestContext.initializeContext();
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

//需要在启动类上添加注解,使该Filter能够被扫描到
@ServletComponentScan({"com.arivan.servlet","com.arivan.filter"})

你可能感兴趣的:(知识点总结,spring,java)