[英]Long running multi threaded application runs 4x slower when deployed to tomcat than when run from command line
When I run this long running process from the command line it takes about 30 seconds to complete. 当我从命令行运行这个长时间运行的进程时,它需要大约30秒才能完成。 When I deploy this same code to tomcat7 and call the same function from a simple Vaadin web application it takes almost 150 seconds. 当我将相同的代码部署到tomcat7并从一个简单的Vaadin Web应用程序调用相同的函数时,它需要将近150秒。 This is the time for a specific function to execute, not anything related to interface slowing it down. 这是特定功能执行的时间,而不是与接口相关的任何事情。
Here's is a simple example that illustrates the problem: 这是一个说明问题的简单示例:
public static void main(String[] args) {
try {
multiCounter(800);
} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}
System.out.println("Completed");
}
public static void multiCounter(int numberOfCounters) throws InterruptedException, ExecutionException
{
//estimate the number of available processors
int maxNumberOfThreads = Runtime.getRuntime().availableProcessors();
//create thread pool and queue for future jobs
ExecutorService pool = Executors.newFixedThreadPool(maxNumberOfThreads);
ArrayList<Future<Integer>> futureJobs = new ArrayList<Future <Integer>>();
for(int index=0; index<numberOfCounters; index++)
{
Callable<Integer> callable = new dummyCalculator();
Future<Integer> future = pool.submit(callable);
futureJobs.add(future);
}
//placeholder for results
ArrayList <Integer> results= new ArrayList <Integer>(0);
//pull completed jobs from queue and extract results,
//adding to results container
for(Future<Integer> future : futureJobs)
{results.add(future.get());}
for(Integer res : results)
{System.out.println("Count:" + res);}
//close thread pool
pool.shutdown();
}
final static class dummyCalculator implements Callable<Integer>
{
@Override
public Integer call() throws Exception {
Integer counter = 0;
for(int p1Index=0; p1Index<800; p1Index++)
{
for(int p2Index=p1Index; p2Index<800; p2Index++)
{
for(int markerIndex=0; markerIndex<200; markerIndex++)
{counter++;}
}
}
return(counter);
}
}
The server I'm running this on has 48 available cores. 我运行它的服务器有48个可用内核。 When I run this code from the command line I get 48 threads running ~98% each. 当我从命令行运行此代码时,我得到48个线程,每个线程运行~98%。 When I run it through tomcat each thread tops out at around 82-86% according to top. 当我通过tomcat运行它时,根据顶部,每个线程最高可达82-86%。 If I decrease the number of threads in the code on tomcat, the % per thread increases. 如果我减少tomcat上代码中的线程数,则每个线程的%增加。 12 threads will get me 92% per thread. 12个线程将获得每个线程92%。 1 thread 99%... 1个线程99%......
Does tomcat do something to limit this tread pool in some way, or have some additional overhead with threads that I am not aware of? tomcat是否会以某种方式限制这个步骤池,或者有一些我不知道的线程的额外开销? Or is there a better way to multi-thread in this case? 或者在这种情况下有更好的多线程方法吗? Some overhead is obviously acceptable, but something doesn't seem right here for it to take that much longer through tomcat. 一些开销显然是可以接受的,但似乎没有什么东西可以让它通过tomcat花更长的时间。
Have you tried to ensure that the total number of threads that Tomcat and your jobs use totals the number of cores on your system? 您是否尝试确保Tomcat和您的作业使用的线程总数总计为系统中的核心数? I would venture to say that you would probably get closer to the 99% execution for those threads. 我冒昧地说,你可能会接近这些线程的99%执行。
The other question that I have is if the Tomcat threads have a higher priority than your worker threads. 我遇到的另一个问题是Tomcat线程的优先级是否高于工作线程。 If that is the case then you should be seeing this difference on a consistent basis. 如果是这种情况,那么你应该在一致的基础上看到这种差异。 I do not recall if you can see the thread priority using jconsole or visualvm but maybe increasing the thread priority of the thread pool should provide more cpu cycle but that will affect tomcat ability to handle web requests. 我不记得你是否可以使用jconsole或visualvm看到线程优先级,但是可能增加线程池的线程优先级应该提供更多的cpu周期,但这会影响tomcat处理Web请求的能力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.