线程池

在Hystrix中Command默认是运行在一个单独的线程池中的,线程池的名称是根据设定的ThreadPoolKey定义的,如果没有设置那么会使用CommandGroupKey作为线程池。

这样每个Command都可以拥有自己的线程池而不会互相影响,同时线程池也可以很好地控制Command的并发量。

设置线程池配置

可以使用Setter来初始化Command在Setter中可以配置线程池的大小和等待队列的长度:

public CommandHelloWorld(String name) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
//配置线程池相关属性,队列大小和线程数
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withMaxQueueSize(10).withCoreSize(10))
//配置运行相关参数如运行超时时间
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(100000000)));
//super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
}

在运行时Hystrix会使用ConcurrencyStrategy来创建线程池以及对应的队列,下面是默认的HystrixConcurrencyStrategy

//线程池中的等待队列
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
/*
* We are using SynchronousQueue if maxQueueSize <= 0 (meaning a queue is not wanted).
* <p>
* SynchronousQueue will do a handoff from calling thread to worker thread and not allow queuing which is what we want.
* <p>
* Queuing results in added latency and would only occur when the thread-pool is full at which point there are latency issues
* and rejecting is the preferred solution.
*/
if (maxQueueSize <= 0) {
//当配置的queue大小小于等于0使用SynchronousQueue,也就是如果没有空闲线程就导致失败
return new SynchronousQueue<Runnable>();
} else {
//其他情况使用阻塞Queue来配置等待队列
return new LinkedBlockingQueue<Runnable>(maxQueueSize);
}
}
//创建线程池的方法
public ThreadPoolExecutor getThreadPool(final HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
ThreadFactory threadFactory = null;
if (!PlatformSpecific.isAppEngine()) {
threadFactory = new ThreadFactory() {
protected final AtomicInteger threadNumber = new AtomicInteger(0); @Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "hystrix-" + threadPoolKey.name() + "-" + threadNumber.incrementAndGet());
thread.setDaemon(true);
return thread;
} };
} else {
threadFactory = PlatformSpecific.getAppEngineThreadFactory();
}
//通过配置的信息创建线程池
return new ThreadPoolExecutor(corePoolSize.get(), maximumPoolSize.get(), keepAliveTime.get(), unit, workQueue, threadFactory);
}

当然以上是默认的ConcurrencyStrategy,Hystrix中可以通过Plugin配置自定义的Strategy:

HystrixPlugins.getInstance().registerConcurrencyStrategy

但这个Plugin是单例的且register方法只能调用一次,也就是无法设置多个Strategy,如果想要使用不同的Strategy只能在方法内部使用一定逻辑来完成。

Semaphore

还有一种不用ThreadPool的方法,是配置SEMAPHORE

HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(10).withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)

这种模式会在主线程自身运行(在调用queue时就会执行)。同时可以通过withExecutionIsolationSemaphoreMaxConcurrentRequests设置并发的数量。

fallback

当配置的等待队列满了的时候Hystrix会直接调用Command的fallback方法。

下面来看下各种情况下代码是执行在哪个线程中的

ThreadPool模式下

超时调用getFallback:Timer线程

线程池队列满调用getFallback:主线程

Command出错调用getFallback:Command线程池

Semaphore模式下

超时调用getFallback:Timer线程

并发数满调用getFallback:主线程

Command出错调用getFallback:主线程

总结

在使用Hystrix时要注意各个代码是运行在哪个线程中的,防止在不必要的地方有阻塞的调用,如在fallback中如果有阻塞耗时操作,那么在队列满时会导致主线程阻塞,可以考虑在Fallback中再调用新Command,这时还要考虑使用不同的线程池防止任务互相排队。

Hystrix框架3--线程池的更多相关文章

  1. Java 并发编程——Executor框架和线程池原理

    Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...

  2. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  3. 并发新特性—Executor 框架与线程池

    兰亭风雨 · 更新于 2018-11-14 09:00:31 并发新特性-Executor 框架与线程池 Executor 框架简介 在 Java 5 之后,并发编程引入了一堆新的启动.调度和管理线程 ...

  4. hystrix熔断器之线程池

    隔离 Hystrix有两种隔离方式:信号量和线程池. 线程池隔离:对每个command创建一个自己的线程池,执行调用.通过线程池隔离来保证不同调用不会相互干扰和每一个调用的并发限制. 信号量隔热:对每 ...

  5. java并发编程(十七)Executor框架和线程池

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17465497   Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动 ...

  6. 转:【Java并发编程】之十九:并发新特性—Executor框架与线程池(含代码)

      Executor框架简介 在Java5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.coc ...

  7. SpringCloud Hystrix熔断之线程池

    服务熔断 雪崩效应:是一种因服务提供者的不可用导致服务调用者的不可用,并导致服务雪崩的过程. 服务熔断:当服务提供者无法调用时,会通过断路器向调用方直接返回一个错误响应,而不是长时间的等待,避免服务雪 ...

  8. 【Java并发编程】:并发新特性—Executor框架与线程池

    Executor框架简介 在Java5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocur ...

  9. Java的Executor框架和线程池实现原理

    Java的Executor框架 1,Executor接口 public interface Executor { void execute(Runnable command); } Executor接 ...

随机推荐

  1. Swift -字符串

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #4dbf56 } p.p2 { margin: 0.0px 0. ...

  2. react native RadioButton(单选按钮)

    刚刚写完这个多选按钮,我觉得没有单选的话,总会觉得有一点点不爽,因为在项目中我也没有用到单选,所以我没有好好研究源码,所以我在Github上找了一下,发现有一个挺好的,简单,不花哨. 在Github上 ...

  3. 批发零售车销门店扫描打印一体移动销售POS机-移动终端销售O2O新模式

    应用领域 终端及移动解决方案 方案概述 通过手持终端对数据进行采集并分析及汇总.利用WIFI网络和专用终端,实时上报终端的各种销量数据,如订单数据.销量数据.库存数据.补货数据.调货数据等. 业务价值 ...

  4. C#开发笔记

    Dictionary 检查后获取值:Dictionary.TryGetValue() KeyValuePair<T, K> 的非泛型形式:DictionaryEntry List 由ILi ...

  5. mssql与mysql 数据迁移

    概要: mssql向mysql迁移的实例,所要用到的工具bcp和load data local infile. 由于订单记录的数据是存放在mssql服务器上的,而项目需求把数据迁移到mysql ser ...

  6. 半吊子学习Swift--天气预报程序-获取天气信息

    昨天申请的彩云天气Api开发者今天上午已审核通过  饭后运动过后就马不停蹄的来测试接口,接口是采用经纬度的方式来获取天气信息,接口地址如下 https://api.caiyunapp.com/v2/ ...

  7. 【BFS】POJ 3414

    直达 -> POJ 3414 Pots 相似题联动–>HDU 1495 非常可乐 题意:两个壶倒水,三种操作,两个桶其中一个满足等于C的最少操作,输出路径.注意a,b互倒的时候能不能倒满, ...

  8. bootstrap学习笔记【转】

    bootstrap是由Twitter公司研发的一个基于HTML,CSS,JavaScript的开源框架,最重要的部分是它的响应式布局.(国内文档翻译官网:http://www.bootcss.com/ ...

  9. 微信公众平台API接口

    简介 微信公众平台消息接口为开发者提供了一种新的消息处理方式.微信公众平台消息接口为开发者提供与用户进行消息交互的能力.对于成功接入消息接口的微信公众账号,当用户发消息给公众号,微信公众平台服务器会使 ...

  10. 在linux下Ant的环境配置

    Ant(英文全称为another neat tool,另一个简洁的工具)是一个基于Java的生成工具,Ant将会被应用到Java项目中. 同样的,现在要来安装Ant(最近要安装的东西还蛮多的=m=), ...