Tomcat потребляет много ресурсов процессора
Вопрос
Tomcat.exe потребляет 75% ресурсов процессора.Кто-нибудь знает, почему это происходит и как это можно уменьшить?
Я использую Tomcat5.5 и J2SDK версии 1.4.2_12.
Решение
Чтобы понять, что происходит, стоит попробовать запустить его под профайлером.Попробуйте YourKit (http://www.yourkit.com/) или Netbeans (http://profiler.netbeans.org/docs/help/5.5/profile_j2ee_profileproject.html).
YourKit лучше интегрируется с tomcat.
Другие советы
Если вы используете 75% ЦП и не понимаете, почему, я предлагаю вам выполнить команду kill -3 для процесса tomcat (ctrl-break, если у вас есть консоль), чтобы получить дамп потока (при высокой нагрузке!).По моему опыту, большинство потоков должны либо простаивать, либо находиться в режиме ожидания ввода-вывода.Найдите любую ветку кода, которая повторяется в трассировках стека, и это ваш вероятный виновник (ожидание без ввода-вывода!).Это «профайлер для бедняков», который зачастую является лучшим и наиболее эффективным способом решения этих проблем.
Лямбда-зонд — очень удобный инструмент для мониторинга Tomcat.
Вы используете четырехпроцессорную систему?Вероятно, в трех из них Tomcat работает на 100%.Сначала я бы проверил наличие в приложении бесконечного цикла или чего-то подобного.
Мои журналы были полны журналов Tomcat.Я удалил их все, и загрузка процессора резко снизилась.
Прежде всего (это относится ко всем Java-приложениям) вы должны определить, какой поток использует процессор.Это возможно в JDK 1.6.Это делается с помощью java.lang.management.ManagementFactory.getThreadMXBean().Вот пример использования (JSP):
<%@ page import="java.lang.management.*, java.util.*" %>
<%!
Map cpuTimes = new HashMap();
Map cpuTimeFetch = new HashMap();
%><%
long cpus = Runtime.getRuntime().availableProcessors();
ThreadMXBean threads = ManagementFactory.getThreadMXBean();
long now = System.currentTimeMillis();
ThreadInfo[] t = threads.dumpAllThreads(false, false);
for (int i = 0; i < t.length; i++) {
long id = t[i].getThreadId();
Long idid = new Long(id);
long current = 0;
if (cpuTimes.get(idid) != null) {
long prev = ((Long) cpuTimes.get(idid)).longValue();
current = threads.getThreadCpuTime(t[i].getThreadId());
long catchTime = ((Long) cpuTimeFetch.get(idid)).longValue();
double percent = (current - prev) / ((now - catchTime) * cpus * 10000);
if (percent > 0 && prev > 0) {
out.println("<li>" + t[i].getThreadName() + " " + percent + " (" + prev + ", " + current + ")");
}
}
cpuTimes.put(idid, new Long(current));
cpuTimeFetch.put(idid, new Long(now));
}
%>
После этого вы можете получить дамп потока и проанализировать код в этом потоке, чтобы устранить чрезмерную загрузку процессора.
Во всех ответах рассказывается, как провести точную диагностику, кроме того, я бы добавил, что, по моему опыту, виноват, вероятно, бесконечный цикл в одном из ваших приложений.
Как сказал J-16 SDiZ, лучше всего запустить профилировщик, чтобы сузить проблему до одного приложения.
Мы только что решили проблему, когда наш экземпляр Tomcat работал с очень высокой загрузкой процессора, увеличиваясь до 100% и более каждые несколько секунд, а затем снова ненадолго снижаясь.Это происходило весь день и всю ночь, независимо от того, выполнял ли сервер какую-либо работу или нет.Мы используем Tomcat 8 с Java 8.
Мы не нашли нашего решения при поиске в Интернете, поэтому публикую его здесь в надежде помочь кому-то еще.
Мы использовали параметр конфигурации в каталоге tomcat/conf/Catalina/localhost, в котором мы указали tomcat другой каталог, отличный от его собственного каталога веб-приложений.XML-файлы в этом каталоге выглядят следующим образом:
<?xml version='1.0'?>
<Context
docBase="/opt/dspace/amaddev/dspace-6.3/webapps/jspui"
reloadable="true"
cachingAllowed="false"/>
И это сработало: Tomcat работал с кодом в этих каталогах, а не в собственном каталоге веб-приложений.Однако у нас возникла проблема с постоянным увеличением загрузки процессора.
Для проверки мы удалили файлы xml из каталога conf/Catalina/localhost и перезапустили Tomcat.Внезапно у нас снова появился нормальный, воспитанный кот.Чтобы указать коту этот другой каталог (где мы компилируем наш код dspace), мы просто использовали запись Host в conf/server.xml и изменили настройку appBase на наш каталог dspace:
<Host name="localhost" appBase="/opt/dspace/amaddev/dspace-6.3/webapps"
unpackWARs="true" autoDeploy="true">
Теперь это обеспечивает то, что мы хотели, с очень низкой загрузкой процессора (ниже 1%), когда сервер тихий.
В моем случае я только что установил Tomcat8 с настройками по умолчанию.Мне пришлось установить параметры памяти -Xms -Xmx
.Как только я увеличил выделение памяти для JVM, загрузка ЦП резко снизилась.
Скорее всего, это вызвано приложениями, которые вы запускаете поверх tomcat.Конечно, если у ваших приложений очень высокий трафик, это также может быть причиной.