Вопрос

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

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

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

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

Спасибо

Это было полезно?

Решение

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

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

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

Это непросто, и, к сожалению, у меня нет кода, который можно было бы легко включить.

Другие советы

Добавляю еще один ответ в ветку, так как наконец-то нашел решение для этой проблемы.

Мое окружение:Была 8.5.5, Кварц 1.8.5, Пружины нет.

Проблема у меня был (указанный выше) неуправляемый поток, вызывающий исключение 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) добавил следующий параметр в путь к классам (в моем случае это папка EAR/lib), чтобы сделать доступным новый WorkManagerThreadExecutor

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

Примечание:в КТЗ-113 или официальная документация Quartz 1.х 2.х нет никакого упоминания о том, как активировать это исправление.

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

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

Примечание:правильный класс орг.кварц.обычай.WorkManagerThreadExecutor для кварца-планировщика-1.8.6 (проверено), или орг.кварц.общий j.WorkManagerThreadExecutor от 2.1.1 включено (не проверено, но проверено в реальных условиях кварцевые банки в репозиториях maven)

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

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

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

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

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

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

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

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

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

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

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

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

Предложение 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», а не как ответ на основную тему.Не нашел способа отличить их.)

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

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

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

Надеюсь, это кому-то поможет..

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top