引入需要的包
<!--核心包-->
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.18</version>
</dependency>
<!--使用切面时需要-->
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.5.18</version>
</dependency>
使用方式一:Java原生编码方式
我们可以通过Hystrix原生编码的方式来对访问的接口进行控制
步骤1:创建针对某个接口的命令对象
/**
* 定义某个接口调用的指令类
* */
public class IhrTokenRequestCommand extends HystrixCommand<MResult<String>> {
public IhrTokenRequestCommand(){
//配置本接口配置参数
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ThreadPoolTestGroup")) //服务分组
.andCommandKey(HystrixCommandKey.Factory.asKey("testCommandKey"))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("ThreadPoolTest"))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(5000)) //超时时长,默认1000
.andThreadPoolPropertiesDefaults( // 配置线程池
HystrixThreadPoolProperties.Setter()
.withCoreSize(50)) // 配置线程池里的线程数
.andCommandPropertiesDefaults( // 配置熔断器
HystrixCommandProperties.Setter()
.withCircuitBreakerEnabled(true) //是否开启熔断机制,默认为true。
.withCircuitBreakerRequestVolumeThreshold(20) //在熔断开关闭合情况下,在进行失败率判断之前,一个采样周期内必须进行至少N个请求才能进行采样统计,目的是有足够的采样使得失败率计算正确,默认为20。
.withCircuitBreakerSleepWindowInMilliseconds(3) // 熔断后的重试时间窗口,且在该时间窗口内只允许一次重试。即在熔断开关打开后,在该时间窗口允许有一次重试,如果重试成功,则将重置Health采样统计并闭合熔断开关实现快速恢复,否则熔断开关还是打开状态,执行快速失败。
.withCircuitBreakerErrorThresholdPercentage(50) //如果在一个采样时间窗口内,失败率超过该配置,则自动打开熔断开关实现降级处理,即快速失败。默认配置下采样周期为10s,失败率为50%。
)
);
}
//实际执行的代码,可主动抛出HystrixTimeoutException、HystrixRuntimeException等异常
@Override
protected MResult<String> run() throws Exception {
return null;
}
//降级方法
@Override
protected MResult<String> getFallback() {
MResult<String> result = new MResult<String>(ResponseCodeEnum.ERROR) ;
return result;
}
}
步骤2:创建实例并执行
MResult<String> result = new IhrTokenRequestCommand().execute();
注意,每次调用都需要创建一个实例
使用方式二:使用Spring的AOP进行控制
通过Spring的AOP,我们可以用更加优雅的方式来控制对接口的访问
步骤1:添加所需切面的配置
在Spring的配置文件中添加以下配置
<aop:aspectj-autoproxy/>
<bean id="hystrixAspect" class="com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect"></bean>
也可以通过JavaConfig的方式来配置
@Configuration
public class HystrixAspectConfiguration {
@Bean
public HystrixCommandAspect hystrixAspect() {
return new HystrixCommandAspect();
}
}
步骤2:在方法上添加注解
public class HystrixResourceApi {
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
},fallbackMethod = "fallbackForGetUser")
public String getUserById(String id) {
throw new RuntimeException("getUserById command failed");
}
/**
* fallback 方法,原方法被降级的时候调用
* */
String fallbackForGetUser(String id) {
return "unknown";
}
}
接着,在需要的地方通过依赖注入的方式来正常的使用该方法即可。
HystrixCommandProperties配置说明
参数 | 说明 | |
---|---|---|
withFallbackEnabled | 是否启用降级处理,如果启用了,则在超时或异常时调用getFallback进行降级处理,默认开启。 | |
withFallbackIsolationSemaphoreMaxConcurrentRequests | fallback方法的信号量配置,配置getFallback方法并发请求的信号量,如果请求超过了并发信号量限制,则不再尝试调用getFallback方法,而是快速失败,默认信号量为10。 | |
withExecutionIsolationThreadInterruptOnFutureCancel | 当隔离策略为THREAD时,当执行线程执行超时时,是否进行中断处理,即Future#cancel(true)处理,默认为false | |
withExecutionIsolationThreadInterruptOnTimeout | 当隔离策略为THREAD时,当执行线程执行超时时,是否进行中断处理,默认为true。 | |
withExecutionTimeoutEnabled | 是否启用执行超时机制,默认为true | |
withExecutionTimeoutInMilliseconds | 执行超时时间,默认为1000毫秒,如果命令是线程隔离,且配置了executionIsolationThreadInterruptOnTimeout=true,则执行线程将执行中断处理。如果命令是信号量隔离,则进行终止操作,因为信号量隔离与主线程是在一个线程中执行,其不会中断线程处理,所以要根据实际情况来决定是否采用信号量隔离,尤其涉及网络访问的情况。 | |
withCircuitBreakerEnabled | 是否开启熔断机制,默认为true。 | |
withCircuitBreakerForceClosed | 是否强制关闭熔断开关,如果强制关闭了熔断开关,则请求不会被降级,一些特殊场景可以动态配置该开关,默认为false。 | |
withCircuitBreakerForceOpen | 是否强制打开熔断开关,如果强制打开可熔断开关,则请求强制降级调用getFallback处理,可以通过动态配置来打开该开关实现一些特殊需求,默认为false。 | |
withCircuitBreakerErrorThresholdPercentage | 如果在一个采样时间窗口内,失败率超过该配置,则自动打开熔断开关实现降级处理,即快速失败。默认配置下采样周期为10s,失败率为50%。 | |
withCircuitBreakerRequestVolumeThreshold | 在熔断开关闭合情况下,在进行失败率判断之前,一个采样周期内必须进行至少N个请求才能进行采样统计,目的是有足够的采样使得失败率计算正确,默认为20。 | |
withCircuitBreakerSleepWindowInMilliseconds | 熔断后的重试时间窗口,且在该时间窗口内只允许一次重试。即在熔断开关打开后,在该时间窗口允许有一次重试,如果重试成功,则将重置Health采样统计并闭合熔断开关实现快速恢复,否则熔断开关还是打开状态,执行快速失败。熔断后将降级调用getFallback进行处理(fallbackEnabled=true),通过Command如下方法可以判断是否熔断了。 | |
isCircuitBreakerOpen | 熔断开关是否打开了,通过“circuitBreakerForceOpen().get() | (!circuitBreakerForceClosed().get() && circuitBreaker.isOpen())”判断。 |
isResponseShortCircuited | isCircuitBreakerOpen=true,且调用getFallback时返回true。 |