Hystrix基本介绍
hystrix是一个容错组件,实现了超时机制和断路器模式。
hystrix提供了熔断和降级。
降级
降级其实就相当于,当我们向一个服务发起请求,当请求超时了,就会把这次请求记录到服务中,然后就会尝试向其他服务发请求,如果还没成功,就对这次请求进行处理(怎么处理取决于业务需求如)就相当于try catch一样的逻辑,当然hystrix底层使用aop来实现的。
熔断
熔断就是有一个阈值,向服务发起请求后,如果不成功,就会记录次数,然后当连续失败次数达到阈值时,下次请求的时候就会直接把这个服务停止。请求有三种状态,可以请求(开),不可请求(关),还有一个中间状态,相当于半开状态,半开状态是什么意思呢,就是可以尝试着去请求,就可以在关闭状态后一段时间,发一个请求尝试一下是否可以请求成功,如果是吧,继续保持关闭状态,如果请求成功,则变成开放状态。
隔离
每当向服务发起一个请求时,就是会发起一个http请求,每一个http请求就要开启一个线程,然后等待服务返回信息,这容易导致线程的堆积,所以就可以用http的URI作为一个标识,然后相同的URI可以开启一个线程池,然后线程池中限定线程数,这样就可以设置拒绝策略,当线程池满了,就可以快速的抛出异常或者拒绝请求,用线程池做到线程隔离来达到限流。
Hystrix基本代码简单实现
引入包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
启动类加注解
@EnableHystrix
写一个测试实例,局部配置就在当前类上加上注解,全局配置就是在yml配置文件里面写配置
package com.example;
import cn.hutool.core.thread.ThreadUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoConroller {
@GetMapping("/test")
/*局部配置*/
/* @HystrixCommand(fallbackMethod = "testFallback",commandProperties={
//设置超时时间
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000"),
//是否开启断路器
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
//统计的时间窗口,默认为10s,一般不需要更改
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "30000"),
//请求最小触发次数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "3"),
//失败率达到多少后跳闸,在统计窗口期中,请求数大于阈值并且失败率达到50,则触发断路,断路器开启,链路中断
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),
//断路后休眠状态的时长,10s,默认为5s,断路10s后断路器进入半开状态
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "80000"),
})*/
@HystrixCommand(fallbackMethod = "testFallback")
/*test和testFallback入参和返回类型必须保持一致*/
public String test(@RequestParam Integer sleepTime){
System.out.println("进入正常方法1");
ThreadUtil.safeSleep(sleepTime);
System.out.println("进入正常方法2");
return "这是正常结果";
}
public String testFallback(@RequestParam Integer sleepTime){
System.out.println("进入兜底方法");
return "这是兜底";
}
}
application.yml全局配置
#全局配置
hystrix:
command:
default:
metrics:
rollingStats:
timeInMilliseconds: 30000 #统计的时间窗口,默认为10s,一般不需要更改
fallback:
enabled: true
circuitBreaker:
enabled: true #是否开启断路器
errorThresholdPercentage: 50 #失败率达到多少后跳闸,在统计窗口期中,请求数大于阈值并且失败率达到60,则触发断路,断路器开启,链路中断
requestVolumeThreshold: 3 #请求最小触发次数
sleepWindowInMilliseconds: 80000 #断路后休眠状态的时长,10s,默认为5s,断路10s后断路器进入半开状态
execution:
isolation:
thread:
interruptOnFutureCancel: true #取消是否中断
interruptOnTimeout: true #超时是否中断
timeoutInMilliseconds: 3000 #超时阈值,单位是毫秒
timeout:
enabled: true
Hystrix结合openfeign使用
1.添加依赖,加入Hystrix和openfeign的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.配置application.yml
logging:
level:
com:
example: debug
server:
port: 8073
spring:
application:
name: nacos-app-c
cloud:
nacos:
discovery:
server-addr: 192.168.33.133:8848
feign:
hystrix:
enabled: true
#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 10000
#指的是建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 10000
hystrix:
command:
default:
metrics:
rollingStats:
timeInMilliseconds: 30000 #统计的时间窗口,默认为10s,一般不需要更改
fallback:
enabled: true
circuitBreaker:
enabled: true #是否开启断路器
errorThresholdPercentage: 50 #失败率达到多少后跳闸,在统计窗口期中,请求数大于阈值并且失败率达到60,则触发断路,断路器开启,链路中断
requestVolumeThreshold: 3 #请求最小触发次数
sleepWindowInMilliseconds: 80000 #断路后休眠状态的时长,10s,默认为5s,断路10s后断路器进入半开状态
execution:
isolation:
thread:
interruptOnFutureCancel: true #取消是否中断
interruptOnTimeout: true #超时是否中断
timeoutInMilliseconds: 3000 #超时阈值,单位是毫秒
timeout:
enabled: true
commandKeyTest:
metrics:
rollingStats:
timeInMilliseconds: 30000 #统计的时间窗口,默认为10s,一般不需要更改
fallback:
enabled: true
circuitBreaker:
enabled: true #是否开启断路器
errorThresholdPercentage: 50 #失败率达到多少后跳闸,在统计窗口期中,请求数大于阈值并且失败率达到60,则触发断路,断路器开启,链路中断
requestVolumeThreshold: 3 #请求最小触发次数
sleepWindowInMilliseconds: 80000 #断路后休眠状态的时长,10s,默认为5s,断路10s后断路器进入半开状态
execution:
isolation:
thread:
interruptOnFutureCancel: true #取消是否中断
interruptOnTimeout: true #超时是否中断
timeoutInMilliseconds: 3000 #超时阈值,单位是毫秒
timeout:
enabled: true
3.启动类上加上注解@EnableHystrix和@EnableFeignClients
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrix
public class CApp {
public static void main(String[] args) {
SpringApplication.run(CApp.class, args);
}
}
4.接口类上:@FeignClient(“被调用的服务器名”,fallback =兜底方法.class)
@FeignClient(value = "nacos-app-a",fallback = AClientFallBack.class)
public interface AClient {
@GetMapping("echo")
String test (@RequestParam("name") String name,@RequestParam("sleepTime") Integer sleepTime);
}
5.兜底方法
@Service
public class AClientFallBack implements AClient {
@Override
public String test(@RequestParam("name") String name, @RequestParam("sleepTime") Integer sleepTime) {
return "兜底";
}
}
6.编写一个测试类,实现的功能是:由于配置文件中配置的是3秒超时阈值,单位是毫秒,和请求最小触发3次数,所以test方式传入的参数时间大于等于三秒后,将重试3次后熔断调用兜底方法
@RestController
public class CController {
@Autowired
private AClient aClient;
@GetMapping("/test")
public String test(@RequestParam(value = "name", defaultValue = "这是默认值") String name,@RequestParam("sleepTime") Integer sleepTime) {
System.out.println("进来了");
String ret = aClient.test(name,sleepTime);
return ret;
}
}