一开始,我的思路是,看看能不能把hystrix的默认线程池给换掉,因为构建HystrixCommand时,支持使用Setter的方式去配置。
如下:
com.netflix.hystrix.HystrixCommand.Setter
final public static class Setter {
// 1
protected final HystrixCommandGroupKey groupKey;
// 2
protected HystrixCommandKey commandKey;
// 3
protected HystrixThreadPoolKey threadPoolKey;
// 4
protected HystrixCommandProperties.Setter commandPropertiesDefaults;
// 5
protected HystrixThreadPoolProperties.Setter threadPoolPropertiesDefaults;
}
-
1处,设置命令组
-
2处,设置命令的key
-
3处,设置线程池的key;hystrix会根据这个key,在一个map中,来查找对应的线程池,如果找不到,则创建一个,并放到map中。
com.netflix.hystrix.HystrixThreadPool.Factory
final static ConcurrentHashMap<String, HystrixThreadPool> threadPools = new ConcurrentHashMap<String, HystrixThreadPool>();
-
4处,命令的相关属性,包括是否降级,是否熔断,是否允许请求合并,命令执行的最大超时时长,以及metric等实时统计信息
-
5处,线程池的相关属性,比如核心线程数,最大线程数,队列长度等
怎么样,可以设置的属性很多,是吧,但是,并没有让我们控制线程池的创建相关的,也没办法替换其默认线程池。
ok,那不用setter的方式,行不行呢?
从构造器入手
HystrixCommand 的构造函数,看看能不能传入自定义的线程池呢?
经过我一开始不仔细的观察,发现有一个构造函数可以传入HystrixThreadPool,ok,就是它了。但是,后面仔细一看,竟然是 package权限,我的子类,和HystrixCommand当然不是一个package下的,所以,访问不了这个构造器。
虽然,可以使用反射,但是,咱们还是守规矩点好了,再看看有没有其他入口。
寻找扩展口
仔细观察下,看看线程池什么时候创建的?
入口在下图,每次new一个HystrixCommand,最终都会调用父类的构造函数:
上图所示处,initThreadPool里面,会去创建线程池,需要注意的是,这里的第一个实参,threadPool,是构造函数的第5个形参,目前来看,传进来的都是null。为啥说这个,我们接着看:
private static HystrixThreadPool initThreadPool(HystrixThreadPool fromConstructor, HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties.Setter threadPoolP