线程池大小多少合适?
概述
通常来说,服务分为两种类型:
也叫计算密集型,当计算机完成任务的时间主要取决于CPU的速度时,计算机受CPU限制(或计算限制):CPU利用率很高,可能在100%的使用时间内持续很多秒或分钟。外围设备产生的中断可能会被缓慢处理或无限期延迟处理。
- IO密集型
完成计算所花费的时间主要由等待I/O操作完成所花费的时间来确定。 这与CPU密集的任务相反。 当请求数据的速率低于其消耗速率时,或者换句话说,请求数据所花费的时间多于处理数据所花费的时间,就会出现这种情况。
那有没有可以落地的实践方法指导呢?Little’s Law。
一个系统请求数
=
请求的到到达率*
平均每个单独请求花费的时间
利用Little’s Law判定线程池大小,也就是
线程池大小 = (线程IO时间+线程CPU时间) / 线程CPU时间 / CPU数目
所需数值分别为:
- 一个请求所消耗的时间
- 线程IO时间+线程CPU时间
- 该请求计算时间
- 线程CPU时间
- CPU数目
请求消耗时间
Web服务中,可以通过Filter来拦截获取该请求前后消耗的时间
1 2 3 4 5 6 7 8 9 10 11 |
public class implements Filter{ public void doFilter(ServletRequest request, ServletResponse response){ long start = System.currentTimeMillis(); try{ }finally{ long cost = System.currentTimeMillis() - start; } } } |
CPU计算时间
CPU计算时间 = 请求总耗时 - CPU IO时间
假设该请求有一个查询DB的操作,只要查询DB的耗时,也就是CPU IO时间,就可以得出CPU计算时间。
可以通过JDK动态代理或者是CGLIB的方式添加AOP切面,来获取线程IO耗时。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class DaoInterceptor implements MethodInterceptor{ @override public Object invoke(MethodInvocation invocation) throws Throwable{ StopWatch watch = new StopWatch(); watch.start(); Object result = null; Throwable t = null; try{ result = invocation.proceed(); }catch(Exception ex){ //handle ex }finally{ // 得出时间 watch.stop(); } return result; } } |
CPU数目
1 |
cat /proc/cpuinfo | grep "processor" | wc -l |
总结
还是需要通过压测来进行微调,以保证配置的正确性。
原文:大专栏 设置线程池大小 · 贰白
原文地址:https://www.cnblogs.com/chinatrump/p/11614932.html
时间: 2024-10-06 00:42:59