这一篇我们将重点介绍一下用Hystrix来做限流器以及服务隔离器。
首先让我们看看官方文档上的工作流程图。
在这里插入图片描述 英文版的流程图看不懂,没关系,咱们还有中文版的工作流程图。
在这里插入图片描述
说完了Hystrix的工作机制之后,接下来,我们来看下Hystrix的两种资源隔离模式。
使用一个线程池用来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列,这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量。
使用一个原子计数器(或信号量)来记录当前有多少个线程正在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃该类型的新请求,若不超过则执行计数操作请求,则计数器+1,请求返回计数器-1,无法处理突发流量。 下图展示了线程池隔离模式和信号量隔离模式的比较。
在这里插入图片描述 接下来就让我们来看看Hystrix的基本配置。Hystrix支持的配置有很多,主要就是Command相关的配置,熔断器相关的配置, 线程池相关的配置。很多配置都有默认值,我们可以合理的使用其默认值。
HystrixCommand支持如下的配置: GroupKey: 该命令属于哪一个组,可以帮助我们更好的组织命令。 CommandKey: 该命令的名称 ThreadPoolKey: 该命令所属线程池的名称,同样配置的命令会共享同一线程池,若不配置,会默认使用GroupKey作为线程池名称。 CommandProperties: 该命令的一些设置,包括断路器的配置,隔离策略,降级设置以及一些监控指标等。 ThreadPoolProerties:关于线程池的配置,包括线程池大小,排队队列的大小等。
配置项 | 配置说明 | 默认值 |
---|---|---|
execution.isolation.strategy | 使用命令调用隔离方式 | 采用线程池隔离 ExecutionIsolationStrategy.THREAD |
execution.isolation.thread.timeoutInMilliseconds | 使用线程隔离时,调用超时时间 | 1秒 |
execution.timeout.enabled | 超时开关 | true |
execution.isolation.thread.interruptOnTimeout | 使用线程池隔离时,是否对命令执行超时 | true |
execution.isolation.semaphore.maxConcurrentRequests | 使用信号量隔离时,命令调用最大的并发数 | 10 |
fallback.isolation.semaphore.maxConcurrentRequests | 使用信号量隔离时,命令fallback(降级)调用最大的并发数 | 10 |
metrics.rollingStats.timeInMilliseconds | 统计滚动的时间窗口 | 5000 |
metrics.rollingStats.numBuckets | 统计窗口的Buckets的数量 | 10 |
metrics.rollingPercentile.enabled | 否开启监控统计功能 | true |
配置项 | 配置说明 | 默认值 |
---|---|---|
circuitBreaker.enabled | 是否启用熔断器 | true |
circuitBreaker.requestVolumeThreshold | 熔断器在整个统计时间内是否开启的阀值 | 默认20秒。也就是10秒钟内至少请求20次,熔断器才发挥起作用 |
circuitBreaker.sleepWindowInMilliseconds | 熔断器默认工作时间 | 5秒.熔断器中断请求5秒后会进入半打开状态,放部分流量过去重试 |
circuitBreaker.errorThresholdPercentage | 当出错率超过50%后熔断器启动 | 50% |
circuitBreaker.forceOpen | 是否强制开启熔断器阻断所有请求 | false |
circuitBreaker.forceClosed | 是否允许熔断器忽略错误 | false |
配置项 | 配置说明 | 默认值 |
---|---|---|
coreSize | 核心线程数,请求高峰时99.5%的平均响应时间 + 向上预留一些即可 | 10 |
maximumSize | 最大线程数 | 10 |
keepAliveTimeMinutes | 线程的有效时长 | 1分钟 |
maxQueueSize | 配置线程池等待队列长度,默认值:-1,-1表示不等待直接拒绝,测试表明线程池使用直接拒绝测试+合适大小的非回缩线程池效率最高,所以不建议修改此值,当使用非回缩线程池时,queueSizeRejectionThreshold,keepAliveTimeMinutes 参数无效 | -1 |
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
@Configuration
public class HystrixConfig {
@Bean
public HystrixCommandAspect hystrixCommandAspect() {
return new HystrixCommandAspect();
}
}
@Service
public class HelloService {
@HystrixCommand(
fallbackMethod = "helloError",
commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2")
},
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "5"),
@HystrixProperty(name = "maximumSize", value = "5"),
@HystrixProperty(name = "maxQueueSize", value = "10")
}
)
public String sayHello(String name) {
try {
Thread.sleep(5000);
return "Hello" + name + "!";
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
public String helloError(String name) {
return "服务器繁忙,请稍后访问!";
}
}
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/hystrixTest.do")
public String hystrixTest() {
return helloService.sayHello("项伟");
}
}
在这里插入图片描述
本文主要首先介绍了Hystrix的工作流程,然后介绍了Hystrix的两种隔离策略,主要是线程池的隔离策略以及信号量的隔离策略,默认的话是线程池的隔离策略,该策略可以应对突发流量。接着就是介绍了Hystrix的基本配置,其配置主要是通过@HystrixCommand
注解来配置的。配置按照功能划分有Command的配置,熔断器(circuitBreaker)的配置以及线程池(threadPool)的配置。最后就是通过一个简单的demo来实际使用Hystrix。
微服务容错限流Hystrix入门 hystrix基本配置项(2)