Hystrix框架3--线程池
线程池
在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--线程池的更多相关文章
- Java 并发编程——Executor框架和线程池原理
Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...
- Java 并发编程——Executor框架和线程池原理
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- 并发新特性—Executor 框架与线程池
兰亭风雨 · 更新于 2018-11-14 09:00:31 并发新特性-Executor 框架与线程池 Executor 框架简介 在 Java 5 之后,并发编程引入了一堆新的启动.调度和管理线程 ...
- hystrix熔断器之线程池
隔离 Hystrix有两种隔离方式:信号量和线程池. 线程池隔离:对每个command创建一个自己的线程池,执行调用.通过线程池隔离来保证不同调用不会相互干扰和每一个调用的并发限制. 信号量隔热:对每 ...
- java并发编程(十七)Executor框架和线程池
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17465497 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动 ...
- 转:【Java并发编程】之十九:并发新特性—Executor框架与线程池(含代码)
Executor框架简介 在Java5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.coc ...
- SpringCloud Hystrix熔断之线程池
服务熔断 雪崩效应:是一种因服务提供者的不可用导致服务调用者的不可用,并导致服务雪崩的过程. 服务熔断:当服务提供者无法调用时,会通过断路器向调用方直接返回一个错误响应,而不是长时间的等待,避免服务雪 ...
- 【Java并发编程】:并发新特性—Executor框架与线程池
Executor框架简介 在Java5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocur ...
- Java的Executor框架和线程池实现原理
Java的Executor框架 1,Executor接口 public interface Executor { void execute(Runnable command); } Executor接 ...
随机推荐
- python调用c\c++
前言 python 这门语言,凭借着其极高的易学易用易读性和丰富的扩展带来的学习友好性和项目友好性,近年来迅速成为了越来越多的人们的首选.然而一旦拿python与传统的编程语言(C/C++)如来比较的 ...
- Redis——学习之路四(初识主从配置)
首先我们配置一台master服务器,两台slave服务器.master服务器配置就是默认配置 端口为6379,添加就一个密码CeshiPassword,然后启动master服务器. 两台slave服务 ...
- LINUX 忘记root密码如何修改
重启linux系统 3 秒之内要按一下回车,出现如下界面 然后输入e 在 第二行最后边输入 single,有一个空格.具体方法为按向下尖头移动到第二行,按"e"进入编辑模式 在后边 ...
- twitter.common.concurrent deadline and defer
此defer非golang中的defer https://tour.golang.org/flowcontrol/12 from twitter.common.concurrent import Ti ...
- Lua笔记
闭包 示例一 function newCounter() return function() -- anonymous function i = i + return i end end c1 = n ...
- jsoup获取图片示例
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.Inp ...
- 网络流dinic实现总结
太羞耻了,搞了半天居然没发现自己写的不是dinic,直到被一道时限紧的题目卡掉才发现 int dfs(int now,int flow,int sum) { if(now==n) return flo ...
- js中自定义构造函数讲解
什么是构造函数? 构造函数其实就是一个函数,只是用途和普通函数,不太一样, 构造函数一般用于初始化对象 <script> function Person(){ this.name=&quo ...
- Windows下ActiveMQ下载、安装部署
1.下载:http://activemq.apache.org/download.html 最新Windows版本 2.安装 (1) 首先配置JAVA环境变量 JAVA_HOME=D:\Progr ...
- @Autowired
1. Spring框架中进行注入式,使用@Autowired. @Autowired可以对成员变量.方法和构造函数进行标注,来完成自动装配的工作,这里必须明确:@Autowired是根据类型进行自动装 ...