Java concurrent threads pool set in the end how much?

Foreword

In our daily business development process, it will be used more or less concurrent functions. So during concurrent use function, it will certainly run into the following problem

Concurrent thread pool set in the end how much it?

v2-a89daf07dc2cf1bc8547d5c5ee561644_hd.png

Usually a little older programmers may have heard such a statement (where N represents the number of CPU)

  1. CPU-intensive applications, the thread size is set to N + 1

  2. IO intensive applications, the thread pool size is set to 2N

This argument in the end is not correct?

In fact, this is far from true. Why do?

First, we have the flip side, assuming that this statement is true, then we do not care how many services are deployed in a single server. Because the size of the thread pool can only audit about the server, so this statement is not correct. It should specifically how to set the size of it?

Assuming that this application is a hybrid of the two, in which the CPU-intensive task that is, but also the IO-intensive, so we changed how to set it? It is not only hard to decide to throw it?

So we in the end how to set the thread pool size of it? Is there some specific practices to guide you landed it? Let's take a deeper look.

Little's Law (Little rule)

v2-5ce2bc68ff5a87df34cfc6c8e3e5dda3_b.jpg

The product of a system request arrival rate and the average number of requests is equal to the time taken for each separate request of

Assuming the server mononuclear, need to ensure that the corresponding service request quantity (QPS): 10, a request actually handle 1 second, each time the server 10 has processed the request, i.e., 10 threads requires

v2-9c56133e587240965bf37977e925a137_b.jpg

Similarly, we can use the law Little (Little's law) to determine the thread pool size. We just need to calculate the request arrival rate and the average time to process. Then, the value of the rule into Little (Little's law) can be calculated from average system requests. Estimated using the following formula

* Thread pool size = ((Thread IO time + thread CPU time) / Time thread the CPU) the CPU number **

Practice

By formula, we need to understand three specific values

  1. A request time consuming (Thread IO time + thread CPU time)

  2. This request time (thread CPU time)

  3. The number of CPU

Request time-consuming

Web services container, can intercept the request before and after the acquisition time consumed by Filter

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 "";
    }
}

CPU 计算时间

CPU 计算时间 = 请求总耗时 - CPU IO time

假设该请求有一个查询 DB 的操作,只要知道这个查询 DB 的耗时(CPU IO time),计算的时间不就出来了嘛,我们看一下怎么才能简洁,明了的记录 DB 查询的耗时。

通过(JDK 动态代理/ CGLIB)的方式添加 AOP 切面,来获取线程 IO 耗时。代码如下,请参考:

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;
    }
}

The number of CPU

The number of logical CPU, thread pool size is provided when the reference number of a CPU

cat /proc/cpuinfo| grep "processor"| wc -l

to sum up

Appropriate configuration thread pool size is actually not easy, but by the above formula and the specific code, we can quickly calculate how much ground this thread pool that setting.

But in the end the end, we still need to be fine-tuned by a pressure test, pressure test test test and only after that we can guarantee the final configuration of the size is accurate.

Welcome to the concern I kind of public-ho [programmers] marks the beginning of the article will be updated on the inside, documentation will be on the inside.

At last

Welcome to share with everyone, like the point of a praise yo remember the article, thanks for the support!


Guess you like

Origin blog.51cto.com/14442094/2438677