使用Spring跟踪应用异常(5)—用Spring进行调度

看来我终于快要结束关于使用Spring追踪错误系列的博客了,对于那些没有读过该系列任何博客的人而言,我正在写一个简单但是非常有用的文章,它是使用Spring应用在日志文件中扫描异常并产生报告的。在该系列博客开始前有一些初始要求:

  1. 搜索某个目录及其子目录(可能)可以找到某一特定类型的文件。
  2. 如果找到一个文件然后检查它的日期:要找它的错误吗?
  3. 如果一个文件被检查出来很新那么就验证它来寻找异常。
  4. 如果它包含异常,它们是我们正在寻找的异常还是别的?
  5. 如果它包含了我们暂时没有考虑到的地方,那么写一份报告记录细节。
  6. 当所有的文件都检查玩了,那么就可以完善报告的格式准备发布。
  7. 使用电子邮件或其它技术发布报告。
  8. 所有的事情会在每天的特定时间进行。

这个博客摘取了8号会议的要求:“所有的事情会在每天的特定时间进行”这意味着实现某种调度。

现在,Java已经存在并发展很长的时间了,这意味着有许多调度任务的方法。都包括了:

  • 使用一个包含 sleep(...) 的简单线程。
  • 使用 TimerTimerTask 对象。
  • 使用 ScheduledExecutorService
  • 使用 Spring的 TaskExecutorTaskScheduler 类。
  • 使用 Spring的 @EnableScheduling@Scheduled 注解 (Spring 3.1 以上)。
  • 使用一个更专业的调度系统。

更专业的调度系统有Quartz (免费) 和 Obsidian (看似更先进,但要花钱)。

Spring,如你所料,包括 Quartz调度的支持;事实上有两种方法将Quartz调度器集成到Spring应用程序,它们是:

  1. 使用JobDetailBean
  2. 使用 MethodInvokingJobDetailFactoryBean

对于这个应用程序,我正在使用Spring中的Quartz与MethodInvokingJobDetailFactoryBean进行集成;原因是使用Quartz可以让我用cron表达式配置我的日程安排,MethodInvokingJobDetailFactoryBean可以简单地使用几行XML快速配置。

Spring和Quartz中的cron表达式所使用的技术毫不羞愧地借鉴了Unix的cron scheduler。有关Quartz如何处理cron表达式的更多信息,好好看一下Quartz cron页面。如果你在创建你自己的cron表达式时需要帮助,那么你可能会发现Cron Maker是一个非常有用的工具。

首先要做的是当配置的Spring和Quartz时需要包含以下POM的工程文件:

          <!-- 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的实例。它有两个属性:你想要在计划周期调用的bean的名称以及你想要调用的bean的方法名称。
  2. 使用CronTriggerFactoryBeanMethodInvokingJobDetailFactoryBean结合到cron表达式
  3. 最后,使用SchedulerFactoryBean安排整个堆

在这三个bean的配置中,你会得到一些看起来像这样的XML:

     <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文件中找到:

# 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文件。更多的信息我会在下一次介绍。


原文链接: captaindebug 翻译: ImportNew.com - 郭楚沅
译文链接: http://www.importnew.com/11884.html
[ 转载请保留原文出处、译者和译文链接。]

关于作者: 郭楚沅

(新浪微博:@Grey_i7

查看郭楚沅的更多文章 >>



相关文章

发表评论

Comment form

(*) 表示必填项

还没有评论。

跳到底部
返回顶部