<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.8</version>
</dependency>
在dubbo的spi加载filter的配置文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter中添加一行: HystrixFilter=com.rt.platform.infosys.base.common.filter.HystrixFilter
dubbo有着比较好的spi拓展点,如果用户需要自定义filter时,可以在这里添加,在dubbo启动时会自动加载。
@Activate(group = Constants.CONSUMER)
public class HystrixFilter implements Filter {
@Override
public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
DubboHystrixCommand command = new DubboHystrixCommand(invoker, invocation);
return command.execute();
}
}
public class DubboHystrixCommand extends HystrixCommand<Result> {
private static final Logger LOGGER = LoggerFactory.getLogger(DubboHystrixCommand.class);
private static final int DEFAULT_THREADPOOL_CORE_SIZE = 30;
private Invoker invoker;
private Invocation invocation;
public DubboHystrixCommand(Invoker invoker, Invocation invocation) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(invoker.getInterface().getName()))
.andCommandKey(HystrixCommandKey.Factory.asKey(String.format("%s_%d", invocation.getMethodName(),
invocation.getArguments() == null ? 0 : invocation.getArguments().length)))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withCircuitBreakerRequestVolumeThreshold(300).withCircuitBreakerSleepWindowInMilliseconds(1000)// 熔断器中断请求1秒后会进入半打开状态,放部分流量过去重试
.withCircuitBreakerErrorThresholdPercentage(50)// 错误率达到50开启熔断保护
.withExecutionTimeoutEnabled(false))// 使用dubbo的超时,禁用这里的超时
.andThreadPoolPropertiesDefaults(
HystrixThreadPoolProperties.Setter().withCoreSize(getThreadPoolCoreSize(invoker.getUrl()))
.withMaxQueueSize(1000).withQueueSizeRejectionThreshold(700)));// 线程池为30
this.invoker = invoker;
this.invocation = invocation;
}
/**
* 获取线程池大小
*
* @param url
* @return
*/
private static int getThreadPoolCoreSize(URL url) {
if (url != null) {
int size = url.getParameter("ThreadPoolCoreSize", DEFAULT_THREADPOOL_CORE_SIZE);
LOGGER.debug("======ThreadPoolCoreSize is:" + size);
return size;
}
return DEFAULT_THREADPOOL_CORE_SIZE;
}
@Override
protected Result run() throws Exception {
return invoker.invoke(invocation);
}
@Override
protected Result getFallback() {
LOGGER.error("come into fall back method,please check it!",getFailedExecutionException());
LOGGER.error("the execution exception is here!",getExecutionException());
return new RpcResult(ResultFactory.failure(PublicExceptionCodeEnum.EX_SYS_BUSY.getCode(),
PublicExceptionCodeEnum.EX_SYS_BUSY.getMsg()));
}
线程隔离(Isolation)
统计器(Metrics) 基于滑动窗口和桶来实现。滑动窗口相当于一个时间窗,在这个时间窗中会有很多请求进入,如果每进入一个请求就统计一次这个时间窗的请求总数会有较低的性能,所以将这个时间窗口分成 十份,每份是一个桶,时间窗滑动到每个桶结束点时就统计一下这个桶内的请求数,就可以统计出整个窗口的请求数了。bucket(桶)一般是窗口的N分之一。
熔断器(Circuit Breaker)
其他配置
threadPoolProperties: