Неуправляемые нити Spring Quartz Websphere Hibernate - PullRequest
6 голосов
/ 06 октября 2008

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

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

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

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

Спасибо

Ответы [ 8 ]

10 голосов
/ 07 октября 2008

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

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

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

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

5 голосов
/ 19 июля 2013

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

Мое окружение : WAS 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) добавили следующую команду dep в classpath (в моем случае это папка EAR / lib), чтобы сделать доступным новый WorkManagerThreadExecutor

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

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

3) добавил следующее в quartz.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 для кварцевого планировщика-1.8.6 (проверено) или org.quartz. commonj .WorkManagerThreadExecutor из 2.1.1 вкл (не проверено, но проверено в реальных банках кварца-commonj в репозиториях Maven)

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

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

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

3 голосов
/ 08 декабря 2008

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

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

2 голосов
/ 18 июля 2013

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

1 голос
/ 22 июля 2013

Предложение 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 голос
/ 16 октября 2010

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

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

1 голос
/ 22 сентября 2009

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

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

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

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

0 голосов
/ 05 мая 2017

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...