Неуправляемые потоки Spring Quartz Websphere Hibernate

Похоже, что наша реализация использования Quartz — JDBCJobStore вместе со Spring, Hibernate и Websphere создает неуправляемые потоки.

Я немного почитал и нашел техническую статью от IBM, в которой говорится, что использование Quartz с Spring приведет к этому. Они предлагают использовать CommnonJ для решения этой проблемы.

Я провел некоторые дополнительные исследования, и единственные примеры, которые я видел до сих пор, связаны со старым планом JobStore, которого нет в базе данных.

Итак, мне было интересно, есть ли у кого-нибудь пример решения этой проблемы.

Спасибо


person boyd4715    schedule 06.10.2008    source источник
comment
Что вы имеете в виду, говоря о неуправляемых потоках?   -  person Alex Miller    schedule 07.10.2008
comment
Наша команда WAS сообщила мне, что когда наше приложение работает, возникают потоки, которые находятся в неуправляемом состоянии, то есть ни к чему не привязаны, сборщик мусора не может к ним добраться. Судя по чтению с веб-сайта IBM, это может произойти при использовании Quartz.   -  person boyd4715    schedule 10.10.2008


Ответы (8)


У нас есть рабочее решение для этого (на самом деле два).

1) Измените исходный код кварца, чтобы использовать поток демона WorkManager для основного потока планировщика. Работает, но требует замены кварты. Мы не использовали это, так как не хотели поддерживать взломанную версию кварца. (Это напомнило мне, что я собирался отправить это в проект, но совершенно забыл)

2) Создайте WorkManagerThreadPool, который будет использоваться в качестве кварцевого пула потоков. Реализуйте интерфейс для кварца ThreadPool, чтобы каждая задача, запускаемая в кварце, была заключена в общий рабочий объект, который затем будет запланирован в WorkManager. Суть в том, что WorkManager в WorkManagerThreadPool должен быть инициализирован до запуска планировщика из потока Java EE (например, при инициализации сервлета). Затем WorkManagerThreadPool должен создать поток демона, который будет обрабатывать все запланированные задачи, создавая и планируя новые рабочие объекты. Таким образом, планировщик (в своем собственном потоке) передает задачи управляемому потоку (рабочему демону).

Не просто, и, к сожалению, у меня нет готового кода для включения.

person Robin    schedule 07.10.2008
comment
Я понимаю, что этот пост устарел, но есть ли у вас пример того, как вы смогли либо изменить Quartz для использования потока демона WorkManager, либо создать WorkManagerThreadPool, который можно использовать в качестве пула потоков Quartz? Я хотел бы использовать Quartz с Websphere, но осознаю ограничения неуправляемых потоков и хочу сделать это правильно. Спасибо. - person user172092; 11.09.2009

Добавление еще одного ответа в ветку, так как я наконец нашел решение для этого.

Моя среда: WAS 8.5.5, Quartz 1.8.5, без Spring.

Проблема, с которой я столкнулся, заключалась в том, что (вышеуказанный) неуправляемый поток вызывал исключение NamingException из ctx.lookup(myJndiUrl), которое вместо этого правильно работало на других серверах приложений (JBoss, Weblogic); на самом деле Webpshere запускал «инцидент» со следующим сообщением:

javax.naming.ConfigurationException: Операция JNDI с именем "java:" не может быть завершена, поскольку среда выполнения сервера не может связать поток операции с каким-либо компонентом приложения J2EE. Это условие может возникнуть, когда клиент JNDI, использующий имя «java:», не выполняется в потоке запроса серверного приложения. Убедитесь, что приложение J2EE не выполняет операции JNDI с именами "java:" в статических блоках кода или в потоках, созданных этим приложением J2EE. Такой код не обязательно выполняется в потоке запроса серверного приложения и поэтому не поддерживается операциями JNDI с именами "java:".

Следующие шаги решили проблему:

1) обновлен до кварца 1.8.6 (без изменений кода), просто maven pom

2) добавил следующее dep в путь к классам (в моем случае это папка EAR /lib), чтобы сделать доступным новый WorkManagerThreadExecutor

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz-commonj</artifactId>
  <version>1.8.6</version>
</dependency>

Примечание: в QTZ-113 или официальной документации Quartz 1.x 2.x нет упоминания о том, как активировать это исправление.

3) добавил следующее вquart.properties ("wm/default" — это JNDI уже настроенного DefaultWorkManager в моем WAS 8.5.5, см. Resources -> AsynchronousBeans -> WorkManagers в консоли WAS):

org.quartz.threadExecutor.class=org.quartz.custom.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default

Примечание. Правильный класс — org.quartz.custom.WorkManagerThreadExecutor дляquartz-scheduler-1.8.6 (проверено) или org.quartz.commonj .WorkManagerThreadExecutor, начиная с 2.1.1 (не тестировалось, но проверено в реальном банки quartz-commonj в репозиториях maven)

4) переместил поиск JNDI в пустой конструктор задания кварца (спасибо m_klovre "Поток вне контейнера J2EE"); то есть конструктор вызывался путем отражения (метод newInstance()) из того же контекста J2EE моего приложения и имел доступ к пространству имен java:global, в то время как метод execute(JobExecutionContext) все еще выполнялся в более бедном контексте, в котором отсутствовали все функции моего приложения. EJB

Надеюсь это поможет.

Пс. в качестве справки вы можете найти здесь пример файлаquart.properties, который я использовал выше

person PaoloC    schedule 19.07.2013
comment
Я знаю, что прошли годы, но есть ли шанс, что вы сможете найти и поделиться полным содержимым файлаquart.properties? - person rodripf; 01.12.2015
comment
Конечно, вот оно - надеюсь, что это поможет. Кроме того, пожалуйста, проголосуйте за мой ответ, если вы найдете его полезным. - person PaoloC; 03.12.2015
comment
Благодарю вас! Но я продолжаю бороться с проблемой. Разница, которую я получил в своей среде, - это Quartz 2.2. Не уверен, что еще я должен попробовать, если я получу аванс, дам вам знать. - person rodripf; 04.12.2015
comment
Я хотел бы прочитать поток m_klovre вне контейнера J2EE, как указано в ответе; но эти форумы закрыты на spring.io. Где еще я могу найти эти подробности? Прокомментируйте, пожалуйста. - person PriyankaW; 06.06.2019

Прочтите эту статью: http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html

в основном, установите свойство taskExecutor в SchedulerFactoryBean для использования org.springframework.scheduling.commonj.WorkManager TaskExecutor, который будет использовать потоки, управляемые контейнером.

person Community    schedule 08.12.2008
comment
На реализацию этого решения у нас ушло 2 минуты (вы можете повторно использовать wm jndi по умолчанию из WAS), и оно отлично работает. - person Stijn Geukens; 22.07.2011

Просто примечание: приведенная выше ссылка на QUARTZ-708 больше недействительна. Эта новая задача (в новой Jira) похоже решает проблему: http://jira.terracotta.org/jira/browse/QTZ-113 (fixVersion = 1.8.6, 2.0.2)

person PaoloC    schedule 18.07.2013

Вы можете проверить приведенную ниже ссылку JIRA на кварце.

http://jira.opensymphony.com/browse/QUARTZ-708

У него есть необходимая реализация WebSphereThreadPool, которую можно использовать с изменениями вquart.properties, как указано, для удовлетворения ваших требований. Надеюсь это поможет.

С уважением, Шива

person Community    schedule 22.09.2009

Вам придется использовать управляемые пулы потоков websphere. Вы можете сделать это через spring и commonj. CommonJ может иметь исполнителя задач, который будет создавать управляемые потоки. Вы даже можете использовать ссылку на ресурс управляемого потока jndi. Затем вы можете внедрить исполняющую задачу commonj в Quartz SchedulerFactoryBean на основе Spring.

См. http://open.bekk.no/boss/spring-scheduling-in-websphere/ и перейдите к разделу «Quartz с CommonJ», чтобы получить дополнительные сведения.

person user355543    schedule 15.10.2010

Предложение от PaoloC для WAS85 и Quartz 1.8.6 также работает на WAS80 (и Quartz 1.8.6) и не требует Spring. (В моей настройке присутствует Spring 2.5.5, но не используется в этом контексте.)

Таким образом, я смог переопределить SimpleJobFactory своим собственным вариантом, используя InjectionHelper для применения CDI к каждому вновь созданному заданию. Внедрение работает как для @EJB (с поиском JNDI аннотированного удаленного бизнес-интерфейса EJB), так и для @Inject (с поиском JNDI CDI BeanManager с использованием сначала нового InitialContext, а затем с использованием этого вновь полученного BM для поиска самого компонента CDI).

Спасибо PaoloC за этот ответ! (Я надеюсь, что этот текст появится как «ответ PaoloC», а не как ответ на основную тему. Не нашел способа провести различие между ними.)

person user2607328    schedule 22.07.2013

Недавно я столкнулся с этой проблемой. Практически вам нужно:

  1. Реализуйте пул потоков, делегировав работу Websphere Work Manager. (Quartz предоставляет только SimpleThreadPool, который запускает задания в неуправляемых потоках). Скажите кварцу использовать этот пул потоков с помощью свойства org.quartz.threadPool.class
  2. Скажите кварцу использовать WorkManagerThreadExecutor (или реализовать пользовательский) по свойству org.quartz.threadExecutor.class
  3. Немного терпения с громоздкими устаревшими веб-контейнерами :)

Вот демонстрация github использования Quartz с Websphere (а также Tomcat).

Надеюсь кому-нибудь поможет..

person pufface    schedule 04.05.2017