как изменить ThreadPoolTaskExecutor во время выполнения через jmx

#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?