如何计算tomcat线程池大小?
- 背景
在我们的日常开发中都涉及到使用tomcat做为服务器,但是我们该设置多大的线程池呢?以及根据什么原则来设计这个线程池呢?
接下来,我将介绍本人是怎么设计以及计算的。
- 目标
确定tomcat服务器线程池大小
- 具体方法
众所周知,tomcat接受一个request后处理过程中,会涉及到cpu和IO时间。其中IO等待时,cpu被动放弃执行,其他线程就可以利用这段时间片进行操作。
所以我们可以采用服务器IO优化的通用规则:
线程大小 = ( (线程io时间 + 线程cpu) / 线程cpu time) * cpu核数
举例: 线程io时间为100ms(IO操作比如数据库查询,同步远程调用等),线程cpu时间10ms,服务器物理机核数为4个。通过上面的公式,我们计算出来的大小是 ((100 + 10 )/10 ) *4 = 44。理论上我们有依据,但是实际计算过程中我们怎么知道线程IO时间和cpu时间呢? 这个就涉及到实际编码过程中的怎么样监控处理时间啦。
下面我介绍本人项目中的做法
1. 通过java 实现内置的filter接口,我们可以拿到一个request消耗的总时间
public class MoniterFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(MoniterFilter.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
long start = System.currentTimeMillis();
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String uri = httpRequest.getRequestURI();
String params = getQueryString(httpRequest);
try {
chain.doFilter(httpRequest, httpResponse);
} finally {
long cost = System.currentTimeMillis() - start;
logger.info("access url [{}{}], cost time [{}] ms )", uri, params, cost);
}
private String getQueryString(HttpServletRequest req) {
StringBuilder buffer = new StringBuilder("?");
Enumeration<String> emParams = req.getParameterNames();
try {
while (emParams.hasMoreElements()) {
String sParam = emParams.nextElement();
String sValues = req.getParameter(sParam);
buffer.append(sParam).append("=").append(sValues).append("&");
}
return buffer.substring(0, buffer.length() - 1);
} catch (Exception e) {
logger.error("get post arguments error", buffer.toString());
}
return "";
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
2. 通过添加切面来监控线程IO耗时(jdk,cglib)
public class DaoInterceptor implements MethodInterceptor {
private static final Logger logger = LoggerFactory.getLogger(DaoInterceptor.class);
@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 (Throwable e) {
t = e == null ? null : e.getCause();
throw e;
} finally {
watch.stop();
logger.info("({}ms)", watch.getTotalTimeMillis());
}
return result;
}
}
通过上述代码就可以计算出相应时间,从而计算出线程大小啦。但是我们就到此为止了吗?
其实还没有,计算出的数值只是存在理论情况下,我们还是需要通过压测工具(Jmeter)来压测一下线服务器,同时根据qps值来动态微调刚才计算出的线程池大小。
如果文章还对大家有实际意义,请推荐一下。
如何计算tomcat线程池大小?的更多相关文章
- Tomcat线程池的深入理解
1.工作机制: Tomcat启动时如果没有请求过来,那么线程数(都是指线程池的)为0: 一旦有请求,Tomcat会初始化minSpareThreads设置的线程数: 2.线程池作用: Tomcat的线 ...
- 详解Tomcat线程池原理及参数释义
omcat线程池有如下参数: maxThreads, 最大线程数,tomcat能创建来处理请求的最大线程数 maxSpareTHreads, 最大空闲线程数,在最大空闲时间内活跃过,但现在处于空闲,若 ...
- 线程池大小设置,CPU的核心数、线程数的关系和区别,同步与堵塞完全是两码事
线程池应该设置多少线程合适,怎么样估算出来.最近接触到一些相关资料,现作如下总结. 最开始接触线程池的时候,没有想到就仅仅是设置一个线程池的大小居然还有这么多的学问,汗颜啊. 首先,需要考虑到线程池所 ...
- 如何决定Web应用的线程池大小
线程池(Thread Pool)在Web应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...
- 发一个可伸缩线程池大小的python线程池。已通过测试。
发一个可伸缩线程池大小的线程池. 当任务不多时候,不开那么多线程,当任务多的时候开更多线程.当长时间没任务时候,将线程数量减小到一定数量. java的Threadpoolexcutor可以这样,py的 ...
- 如何决定 Web 应用的线程池大小
在部署 web 应用到生产环境,或者在对 web 应用进行性能测试的时候,经常会有人问:如何决定 web 应用线程池大小?决定一个 IO 阻塞型 web 应用的线程池大小是一项很艰巨的任务.通常是通过 ...
- 05 - Tomcat 线程池的配置与优化
添加 Executor 在server.xml中的Service节点里面,增加executor节点,然后配置connector的executor属性,如下: <Executor name=&qu ...
- spring定时任务ThreadPoolTaskScheduler使用注意事项之线程池大小
背景 最近小伙伴解决了一个工单,描述为"手工推送案件无法推,提示token失效",当前工单状态为待关闭,解决方案为"东软接口不稳定造成的,东软的接口恢复正常后,问题解决& ...
- Java-如何合理的设置线程池大小
想要合理配置线程池线程数的大小,需要分析任务的类型,任务类型不同,线程池大小配置也不同. 配置线程池的大小可根据以下几个维度进行分析来配置合理的线程数: 任务性质可分为:CPU密集型任务,IO密集型任 ...
随机推荐
- 漫谈NIO(2)之Java的NIO
1.前言 上章提到过Java的NIO采取的是多路IO复用模式,其衍生出来的模型就是Reactor模型.多路IO复用有两种方式,一种是select/poll,另一种是epoll.在windows系统上使 ...
- docker学习(2)--基础命令
转载请注明源出处:http://www.cnblogs.com/lighten/p/6875355.html 1.基本命令 搭建好docker环境之后,使用docker help命令查看docker的 ...
- Vue中子组件调用父组件的方法
Vue中子组件调用父组件的方法 相关Html: <!DOCTYPE html> <html lang="en"> <head> <meta ...
- rails中 flash 和 flash.now的区别
Flash[:notice]’s message will persist to the next action and should be used when redirecting to anot ...
- sql日期格式处理
sql server中使用convert来取得datetime数据类型样式(全) 日期数据格式的处理,两个示例: CONVERT(varchar(16), 时间一, 20) 结果:2007-02-01 ...
- 爬虫实战(二) 51job移动端数据采集
在上一篇51job职位信息的爬取中,对岗位信息div下各式各样杂乱的标签,简单的Xpath效果不佳,加上string()函数后,也不尽如人意.因此这次我们跳过桌面web端,选择移动端进行爬取. ...
- mongodb-添加或删除字段
1 .添加一个字段. url 代表表名 , 添加字段 content. 字符串类型. db.url.update({}, {$set: {content:""}}, {multi ...
- vscode 常用配置
{ "workbench.iconTheme": "vscode-icons", "editor.tabSize": 2, "ed ...
- [转载]Angular4 组件通讯方法大全
组件通讯,意在不同的指令和组件之间共享信息.如何在两个多个组件之间共享信息呢. 最近在项目上,组件跟组件之间可能是父子关系,兄弟关系,爷孙关系都有.....我也找找了很多关于组件之间通讯的方法,不同的 ...
- python学习之参数传递
^参数传递分为定义(形参)和调用(实参)两种情况.^ 1. 定义(形参) 默认参数 def func(x, y=None): # 任何时候必须 优先定义 位置参数 # 默认参数和可变参数*args 顺 ...