Dubbo-线程池
-
fix: 表示创建固定大小的线程池。也是Dubbo默认的使用方式,默认创建的执行线程数为200,并
且是没有任何等待队列的。所以再极端的情况下可能会存在问题,比如某个操作大量执行时,可能
存在堵塞的情况。后面也会讲相关的处理办法。 -
cache: 创建非固定大小的线程池,当线程不足时,会自动创建新的线程。但是使用这种的时候需
要注意,如果突然有高TPS的请求过来,方法没有及时完成,则会造成大量的线程创建,对系统的
CPU和负载都是压力,执行越多反而会拖慢整个系统。
默认是fix
自定义线程池
在真实的使用过程中可能会因为使用fix模式的线程池,导致具体某些业务场景因为线程池中的线程数量
不足而产生错误,而很多业务研发是对这些无感知的,只有当出现错误的时候才会去查看告警或者通过
客户反馈出现严重的问题才去查看,结果发现是线程池满了。
所以可以在创建线程池的时,通过某些手段对这个线程池进行监控,这样就可以进行及时的扩缩容机器或者告警。
会在创建线程池后进行对其监控,并且及时作出相应处理
/**
* 创建线程池后进行对其监控
*/
public class WatchingThreadPool extends FixedThreadPool implements Runnable {
private static final Logger LOGGER= LoggerFactory.getLogger(WatchingThreadPool.class);
private static final double ALARM_PERCENT = 0.90;
/**
* URL与线程池的对应
*/
private final Map<URL, ThreadPoolExecutor> THREAD_POOLS =new ConcurrentHashMap<>();
public WatchingThreadPool() {
//每隔3秒钟打印线程的使用情况
Executors.newSingleThreadScheduledExecutor()
.scheduleAtFixedRate(this, 1, 3, TimeUnit.SECONDS);
}
@Override
public Executor getExecutor(URL url) {
final Executor executor = super.getExecutor(url);
if(executor instanceof ThreadPoolExecutor){
THREAD_POOLS.put(url, (ThreadPoolExecutor)executor);
}
return executor;
}
@Override
public void run() {
/**
* 遍历线程池,如果超出指定的部分,进行操作,比如接入公司的告警系统或者短信平台
*/
for(Map.Entry<URL,ThreadPoolExecutor> entry: THREAD_POOLS.entrySet()){
final URL url = entry.getKey();
final ThreadPoolExecutor executor = entry.getValue();
//当前执行中的线程数
int activeCount = executor.getActiveCount();
//核心线程数
int corePoolSize = executor.getCorePoolSize();
//使用率
double used=(double)activeCount/corePoolSize;
//使用率
double used = (double) activeCount / corePoolSize ;
//final int usedNum = (int) (used * 100);
//final int usedNum = (int) (used * 100);
LOGGER.info("线程池执行状态: [{}/{}]: used {}% ", activeCount, corePoolSize, used*100 );
if (used >= ALARM_PERCENT) {
LOGGER.error("超出警戒值!host:{}, used-{} , URL:{}", url.getIp(), used*100, url);
}
}
}
}
- 在META-INF/dubbo目录下建立对象的文件
META-INF/dubbo/org.apache.dubbo.common.threadpool.ThreadPool
watching=com.liu.threadpool.WatchingThreadPool
- 配置
dubbo.provider.threadpool=watching
或者xml
<dubbo:protocol threadpool="xxx" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置threadpool时,使用此配置 -->
<dubbo:provider threadpool="xxx" />