#java #spring #threadpool #jmx #mbeans
#java #spring #threadpool #jmx #mbeans
Вопрос:
У меня возникли проблемы с изменением моих свойств MBean через JConsole. У меня есть компонент для обработки потоков, который вызывается с:
public static void main(String[] args) throws Exception {
// JMX
new SimpleJmxAgent();
// spring executor context
ApplicationContext ctx = new FileSystemXmlApplicationContext(
"src/resources/ThreadContent.xml");
startThreads(ctx);
}
private static void startThreads(ApplicationContext ctx) {
TaskExecutor tE = (TaskExecutor) ctx.getBean("TaskExecutor");
System.out.println("Starting threads");
for (int i = 0; i < 10; i ) {
tE.execute(new RepeatingGrpPoC());
}
ThreadContent.xml содержит все значения свойств по умолчанию.
SimpleJmxAgent выглядит следующим образом:
public SimpleJmxAgent() {
mbs = ManagementFactory.getPlatformMBeanServer();
// Spring context - used to load MBeans
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource(
"resources/JMXcontent.xml"));
// Unique identification of MBeans
ThreadPoolManager threadBean = (ThreadPoolManager) factory.getBean("ThreadPoolBean");
ObjectName threadName = null;
try {
// Uniquely identify the MBeans and register them with the platform MBeanServer
threadName = new ObjectName("THREADING:name=ThreadBean");
mbs.registerMBean(threadBean, threadName);
} catch(Exception e) {
e.printStackTrace();
}
У меня есть ThreadPoolManager, наследуемый от ThreadPoolTaskExecutor, чтобы предоставить ему доступ к методам получения и установки свойств потока, таким как:
public void setCorePoolSize(int corePoolSize)
Редактировать:
Я реализовал использование:
public void setCorePoolSize(int corePoolSize){
super.setCorePoolSize(corePoolSize);
}
завернутый в:
public void changeCorePoolSize(int x){
setCorePoolSize(x);
}
Итак, теперь операция отображается на вкладке MBeans. Однако атрибуты отображаются в виде значений, отличных от используемых. Я установил в своем ThreadContext.xml
property name="corePoolSize" value="5"
Однако при просмотре атрибут устанавливается равным 1, что является значением по умолчанию. Я могу изменить это через Jconsole с помощью changeCorePoolSize
операции, но это имеет лишь косметический эффект, изменяя отображаемое значение, но не изменяя текущий процесс, в котором все еще выполняется 5 TaskExecutor
потоков.
Я что-то упускаю в том, что я делаю? Что может вызвать разрыв между свойствами, которые я настраиваю через ThreadContext.xml и это отображается в атрибутах в Jconsole?
Ответ №1:
Уменьшения corePoolSize должно быть достаточно, чтобы уменьшить количество активных потоков, но это вступает в силу только после завершения текущих команд.
Остерегайтесь эффекта maxPoolSize, который может увеличить количество активных потоков, если рабочая очередь заполнена.
Если вам интересно, мы упаковали JMX-совместимый утилитарный модуль ThreadPoolExecutor с поддержкой JMX и предоставляем его с помощью простой конфигурации на основе пространства имен spring XML. Он предоставляет как показатели (activeCount, completedTackCount и т.д.), Так и параметры конфигурации среды выполнения (corePoolSize, maxPoolSize). Вам просто нужно объявить :
<beans
xmlns:management="http://www.xebia.fr/schema/xebia-management-extras"
... >
<!-- MBeanExporter is in charge of registering the ExecutorService MBean -->
<context:mbean-export />
<management:executor-service
id="my-executor"
pool-size="1-10"
queue-capacity="5"
keep-alive="5"
rejection-policy="ABORT" />
...
<beans>
Библиотека содержит страницу JSP и плагин Hyperic HQ для мониторинга этих пулов потоков.
Этот <executor-service /> поставляется вместе со многими другими дополнительными функциями JMX для облегчения мониторинга общих компонентов (dbcp, util.concurrent, cxf, jms и т.д.) И предлагается под лицензией на программное обеспечение Apache для бизнеса по адресуhttp://code.google.com/p/xebia-france/wiki/XebiaManagementExtras .
Надеюсь, это поможет,
Cyrille
Ответ №2:
Используйте super
для вызова метода в суперклассе, чтобы избежать бесконечного цикла:
public void setCorePoolSize(int corePoolSize){
super.setCorePoolSize(corePoolSize);
}
Ответ №3:
Вам нужен super.setCorePoolSize(corePoolSize);
Ответ №4:
Если я правильно понимаю, вы инициализируете пул с размером ядра 5, но затем во время выполнения сбрасываете размер пула до 1. Когда вы говорите: «текущий процесс, в котором все еще работают 5 потоков TaskExecutor«, это 5 занятых потоков или 5 незанятых потоков?
Если они заняты, сброс размера ядра не вступит в силу до тех пор, пока 4 «лишних» потока не станут простаивать.
Комментарии:
1. Привет, Николас, я не выполняю сброс во время выполнения. Просто, когда я проверяю его значение в Jconsole, оно отображается как 1. Я думаю, что это значение по умолчанию. В Jconsole можно наблюдать 5 экземпляров потоков TaskExecutor. Итак, почему это не будет отображать 5, а не 1?