Hystrix是Netflix开源的一款容错系统,能帮助使用者码出具备强大的容错能力和鲁棒性的程序。如果某程序或class要使用Hystrix,只需简单继承HystrixCommand/HystrixObservableCommand并重写run()/construct(),然后调用程序实例化此class并执行execute()/queue()/observe()/toObservable()。
项目中如何使用Hystrix
<!-- 依赖版本 -->
<hystrix.version>1.3.16</hystrix.version>
<hystrix-metrics-event-stream.version>1.1.2</hystrix-metrics-event-stream.version>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>${hystrix.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>${hystrix-metrics-event-stream.version}</version>
</dependency>
调用execute():以同步堵塞方式执行run()
SunshineGroupGiftInsuranceResponseProto.SunshineGroupGiftInsuranceResponse.Builder insuranceResponse = (SunshineGroupGiftInsuranceResponseProto.SunshineGroupGiftInsuranceResponse.Builder) new SunshineGroupHystrixService(insuranceReq).execute();
queue():以异步非堵塞方式执行run()
Future future = new SunshineGroupHystrixService(insuranceReq,sunshine_key,requestUrl).queue();
SunshineGroupGiftInsuranceResponseProto.SunshineGroupGiftInsuranceResponse.Builder insuranceResponse2 = ( SunshineGroupGiftInsuranceResponseProto.SunshineGroupGiftInsuranceResponse.Builder) future.get();
HystrixCommand的observe()与toObservable()的区别:
1)observe()会立即执行HelloWorldHystrixCommand.run();toObservable()要在toBlocking().single()或subscribe()时才执行HelloWorldHystrixCommand.run()
2)observe()中,toBlocking().single()和subscribe()可以共存;在toObservable()中不行,因为两者都会触发执行HelloWorldHystrixCommand.run(),这违反了同一个HelloWorldHystrixCommand对象只能执行run()一次原则
public class DongkHelloWorld extends HystrixCommand<String> {
private final String name;
public CommandHelloWorld(String name) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")) //必须
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(500)) //超时时间
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("ExampleGroup-pool")) //可选,默认 使用 this.getClass().getSimpleName();
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(4)));
this.name = name;
}
@Override
protected String run() throws InterruptedException {
System.out.println("www.dongkit.com");
TimeUnit.MILLISECONDS.sleep(1000);
return "东科教育 " + name + "!";
}
@Override
protected String getFallback() { //简单来说,就是run方法抛异常,超时,线程/信号量reject、短路
return "东科 "+"Fallback";
}
}
@Test
public void fallbackTest(){
assertEquals("东科教育,高薪就业",new CommandHelloWorld("World").execute());
}
下面为各种熔断策略
复杂版;
public SunshineGroupHystrixService(
SunshineGroupGiftInsuranceRequestProto.SunshineGroupGiftInsuranceRequest.Builder insuranceReq,
String sunshineKey, String requestUrl) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SunshineGroup"))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("ThreadPoolTest"))//我们通过andThreadPoolKey配置使用命名为ThreadPoolTest的线程池,实现与其他命名的线程池天然隔离
.andCommandPropertiesDefaults( // 配置信号量隔离
HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE) // 信号量隔离 // 设置了信号量隔离后,线程池配置将变无效
.withExecutionIsolationSemaphoreMaxConcurrentRequests(3) //意味着信号量最多允许执行run的并发数为3,超过则触发降级
.withFallbackIsolationSemaphoreMaxConcurrentRequests(1) )//意味着信号量最多允许执行fallback的并发数为1,超过则抛异常fallback execution rejected
.andCommandPropertiesDefaults(// 配置熔断器
HystrixCommandProperties.Setter()
.withExecutionIsolationThreadInterruptOnTimeout(true)//超时后是否中断
// .withCircuitBreakerRequestVolumeThreshold(20)//可以配置失败次数阀值,超过进入熔点
// .withCircuitBreakerErrorThresholdPercentage(50)//请求错误率大于50%时就熔断
// .withCircuitBreakerForceOpen(true) // 置为true时,所有请求都将被拒绝,直接到fallback
// .withCircuitBreakerForceClosed(true) // 置为true时,将忽略错误
// .withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE) // 信号量隔离
// .withExecutionTimeoutInMilliseconds(5000))
.andThreadPoolPropertiesDefaults( //设置线程池里的线程数=3,然后循环>3次和<3次,最后查看当前所有线程名称
HystrixThreadPoolProperties.Setter()
.withCoreSize(3) // 配置线程池里的线程数
));//可以配置失败的百分比阀值,超过进入熔断
this.insuranceReq = insuranceReq;
this.sunshineKey = sunshineKey;
this.requestUrl = requestUrl;
}
-
要想使用hystrix,只需要继承HystrixCommand或HystrixObservableCommand
-
4个命令执行方法:execute()、queue()、observe()、toObservable()这4个方法用来触发执行run()/construct(),一个实例只能执行一次这4个方法,特别说明的是HystrixObservableCommand没有execute()和queue()。
-
fallback(降级):使用fallback机制很简单,继承HystrixCommand只需重写getFallback(),继承HystrixObservableCommand只需重写resumeWithFallback(),比如HelloWorldHystrixCommand加上下面代码片段
@Override
protected String getFallback() {
return "fallback: " + name;
}
-
隔离策略:hystrix提供了两种隔离策略:线程池隔离和信号量隔离。hystrix默认采用线程池隔离。
-
熔断机制:熔断机制相当于电路的跳闸功能,举个栗子,我们可以配置熔断策略为当请求错误比例在10s内>50%时,该服务将进入熔断状态,后续请求都会进入fallback。