Статьи

Отслеживание исключений — часть 5 — планирование с помощью Spring

Снимок экрана 2014-04-21 в 12.12.34 Похоже, что я наконец-то подхожу к концу этой серии блогов по отслеживанию ошибок с использованием Spring, а для тех, кто еще не читал ни одного блога из этой серии, я пишу простое, но почти промышленное приложение Spring. сканирует исключения в файлах журналов, а затем создает отчет. С первого блога в серии, это были мои начальные требования:

  1. Поиск в заданном каталоге и его подкаталогах (возможно) в поисках файлов определенного типа.
  2. Если файл найден, проверьте его дату: нужно ли искать ошибки?
  3. Если файл достаточно молодой, чтобы его можно было проверить, проверьте его и найдите исключения.
  4. Если в нем есть исключения, это те, кого мы ищем, или они были исключены?
  5. Если он содержит исключения, которые нам нужны, добавьте детали в отчет.
  6. После проверки всех файлов отформатируйте отчет, готовый к публикации.
  7. Опубликуйте отчет по электронной почте или другим способом.
  8. Все это будет работать в определенное время каждый день

В этом блоге рассматривается требование № 8: «Все будет выполняться в определенное время каждый день», а это означает реализацию какого-либо планирования.

Сейчас Java существует очень давно, а это значит, что есть несколько способов планирования задачи. Они варьируются от:

  • Используя простой поток с длинным sleep(...) .
  • Использование объектов Timer и TimerTask .
  • Использование ScheduledExecutorService .
  • Использование Spring TaskExecutor и TaskScheduler классов.
  • Использование аннотаций Spring @EnableScheduling и @Scheduled (Spring 3.1 и выше).
  • Использование более профессионального расписания.

Более профессиональное разнообразие планировщиков варьируется от Кварца (бесплатно) до Обсидиана (казалось бы, гораздо более продвинутый, но стоит денег). Spring, как и следовало ожидать, включает поддержку Quartz Scheduler; на самом деле есть два способа интеграции Quartz Scheduler в ваше приложение Spring:

  1. Использование JobDetailBean
  2. Использование MethodInvokingJobDetailFactoryBean .

Для этого приложения я использую интеграцию Spring Quartz вместе с MethodInvokingJobDetailFactoryBean ; причина в том, что использование Quartz позволяет мне настроить расписание с помощью выражения cron, а MethodInvokingJobDetailFactoryBean можно настроить быстро и просто, используя несколько строк XML.

Техника выражения cron, используемая Spring и Quartz, была бесстыдно взята из планировщика cron Unix . Для получения дополнительной информации о том, как Quartz работает с выражениями cron, взгляните на страницу cron Quartz . Если вам нужна помощь в создании собственных выражений cron, тогда вы обнаружите, что Cron Maker — действительно полезная утилита.

Первое, что нужно сделать при настройке Spring и Quartz, это включить следующие зависимости в файл проекта POM:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- QuartzJobBean is in spring-context-support.jar -->
          <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-context-support</artifactId>
               <version>${org.springframework-version}</version>
               <exclusions>
                    <!-- Exclude Commons Logging in favour of SLF4j -->
                    <exclusion>
                         <groupId>commons-logging</groupId>
                         <artifactId>commons-logging</artifactId>
                    </exclusion>
               </exclusions>
          </dependency>
          <!-- Spring + Quartz need transactions -->
          <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-tx</artifactId>
               <version>${org.springframework-version}</version>
          </dependency>
          <!-- Quartz framework -->
          <dependency>
               <groupId>org.quartz-scheduler</groupId>
               <artifactId>quartz</artifactId>
               <version>1.8.6</version>
               <!-- You can't use Quartz two with Spring 3 -->
          </dependency>

Это довольно просто с одним крошечным «Gotcha» в конце. Во-первых, поддержка Spring в Quartz находится в spring-context-support-3.2.7.RELEASE.jar (замените ваш номер версии Spring, если это применимо). Во-вторых, вам также необходимо включить библиотеку транзакций Spring — spring-td-3.2.7.RELEASE.jar . Наконец, вам нужно включить версию планировщика Quartz; однако будьте осторожны, так как Spring 3.x и Quartz 2.x не работают вместе «из коробки» (хотя, если вы посмотрите вокруг, есть специальные исправления, которые можно найти). Я использовал Quartz версии 1.8.6, которая делает именно то, что мне нужно.

Следующее, что нужно сделать, это разобраться в конфигурации XML, и это включает в себя три шага:

  1. Создайте экземпляр MethodInvokingJobDetailFactoryBean . У него есть два свойства: имя компонента, который вы хотите вызывать с запланированным интервалом, и имя метода этого компонента, который вы хотите вызвать.
  2. CronTriggerFactoryBean с выражением cron с помощью CronTriggerFactoryBean
  3. И, наконец, составьте расписание для всего кабачка, используя SchedulerFactoryBean

Настроив эти три bean-компонента, вы получите XML, который выглядит примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<bean id="FileLocatorJob"
          class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
 
          <property name="targetObject" ref="errorTrackService" />
          <property name="targetMethod" value="trackErrors" />
 
     </bean>
 
     <bean id="FileLocatorTrigger"
          class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
          <property name="jobDetail" ref="FileLocatorJob" />
          <!-- run every morning at 2 AM -->
          <property name="cronExpression" value="${cron.expression}" />
     </bean>
 
     <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
          <property name="triggers">
               <list>
                    <ref bean="FileLocatorTrigger" />
                    <!-- Add other triggers for other jobs (if any) here <ref bean="" /> -->
               </list>
          </property>
     </bean>

Обратите внимание, что я использовал заполнитель для моего выражения cron. Фактическое выражение cron можно найти в файле app.properties :

1
2
3
4
5
# run every morning at 2 AM
cron.expression=0 0 2 * * ?
 
# Use this to test the app (every minute)
#cron.expression=0 0/1 * * * ?

Здесь у меня есть два выражения: одно, которое планирует выполнение задания на 2 часа утра и другое, закомментированное, которое запускает задание каждую минуту. Это пример того, что приложение не совсем промышленно. Если бы существовало «правильное» приложение, я бы, вероятно, использовал разные наборы свойств в каждой среде (DEV, UAT, production и т. Д.).

Осталось только пару шагов, прежде чем это приложение может быть выпущено, и первым из них является создание исполняемого файла JAR. Подробнее об этом в следующий раз.

  1. Отслеживание исключений приложений с помощью Spring
  2. Отслеживание исключений в Spring — часть 2 — шаблон делегата
  3. Отчеты об отслеживании ошибок — часть 3 — стратегия и пакет
  4. Отслеживание исключений — часть 4 — отправитель почты Spring