8. Hystrix服务限流
大约 3 分钟
Hystrix关键特性:服务降级、服务熔断、服务限流
1. Hystrix服务限流(服务隔离)
通过线程池或者信号量判断是否已满,超出容量的请求直接降级,以达到限流的作用。在springcloud架构的系统中,可以在网关启用Hystrix,进行限流处理,每个微服务也可以各自启用Hystrix进行限流。
两种资源隔离模式:线程池隔离模式
、信号量隔离模式
1.1 线程池隔离模式
使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)。
1.2 信号量隔离模式
使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)。
2. Hystrix限流配置
同之前配置一样,引依赖、配yml、启动类激活注解,业务处理类。
2.1 引入Hystrix依赖
pom引入hystrix依赖(具体版本根据自己环境决定):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.5.18</version>
</dependency>
2.2 启动类添加激活注解
2.3 yml
4、业务类的配置
1)线程池隔离的设置
//线程池隔离的设置
@HystrixCommand(
groupKey="test-provider",
threadPoolKey="test-provider",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "20"),//线程池大小
@HystrixProperty(name = "maximumSize", value = "30"),//最大线程池大小
@HystrixProperty(name = "maxQueueSize", value = "20"),//最大队列长度
@HystrixProperty(name = "keepAliveTimeMinutes", value = "2")//线程存活时间
},commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy",value = "THREAD")
}
2)信号量隔离的设置
//信号量隔离的设置
@HystrixCommand(
//用来设置降级方法
fallbackMethod = "myTestFallbackMethod",
commandProperties = {
//进行熔断配置
//条件1,设置在滚动时间窗口中,断路器的最小请求数(没有达到不会熔断)。默认20。
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold" ,value = "10"),
//条件2,设置断路器打开的错误百分比。在滚动时间内,在请求数量超过requestVolumeThreshold的值,且错误请求数的百分比超过这个比例,断路器就为打开状态。
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage" ,value = "30"),
//条件3,设置滚动时间窗的长度,单位毫秒。这个时间窗口就是断路器收集信息的持续时间。断路器在收集指标信息的时会根据这个时间窗口把这个窗口拆分成多个桶,每个桶代表一段时间的指标,默认10000.
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds" ,value = "10000"),
//设置当断路器打开之后的休眠时间,休眠时间结束后断路器为半开状态,断路器能接受请求,如果请求失败又重新回到打开状态,如果请求成功又回到关闭状态
//单位是毫秒
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds" ,value = "3000"),
//配置信号量隔离
//配置信号量的数值
@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests",value = "100"),
//选择策略为信号量隔离
@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
//设置HystrixCommand执行的超时时间,单位毫秒
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000000000")
}
)
public String Test(){
....
}
public String myTestFallbackMethod() {
log.info("========myTestFallbackMethod=========");
return "myTestFallbackMethod";
}
线程池隔离与信号量隔离的最大区别在于发送请求的线程,信号量是采用调用方法的线程,而线程池则是用池内的线程去发送请求