@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
long t = System.nanoTime();
long a = 0;
long times = Long.valueOf(req.getParameter("times"));
for (int i = 0; i < times; i++) {
a = a + 1;
}
long timeCost = (System.nanoTime() - t) / 1000000;
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("success.times:" + times + ",cpuTimeCost(ms):" + timeCost);
out.flush();
out.close(); // 这里本来不需要close,但是压测请求过多后,会出现因为没及时关闭流,而导致java.net.SocketException:Connect reset
}
在上述servlet的doGet方法中,没有sleep模拟IO。其中servlet传参times=1000000。jmeter测试结果如下:
线程循环次数 线程数 平均响应时间(毫秒) tps cpu100 1 84 11.6 100%
100 2 84 22.4 100%
100 3 129 22.5 100%
从统计结果看到,在2个并发情况就把机器资源占满了。在3个并发时候tps已经没有上升空间了。
按公式,线程数=84/84 * 2 = 2,在2个线程时候就达到资源最高利用了。
上面2个例子都是以cpu为瓶颈的场景,如果数据库是瓶颈,那么就要响应地调整了公式中的项了,但原理都是一样的,这里就不再举例验证了。所以,在系统的并发数调优时,不能只从cpu的数量来加1或减一,而要从瓶颈资源到角度去做相应的判断。当然,实际并发调优还受诸多因素影响,如http服务器,web容器的参数,jvm设置等等,本文只是从瓶颈资源的角度看待并发数。后续会继续探讨。