ATG应用之旅

专注B2B电子商务完整解决方案、产品选型、实施、运营、开发、项目过程

导航

ATG中的定时Job处理

一、ATG中定时Job核心处理Module

在ATG中核心的定时Job管理是放在Schedule这个Module下的,所以如果想要在你的应用拥有定时执行Job的能力,必须要在打包脚本中包含ScheduleModule。但是在生产环境中更为常见的做法是将ScheduleModule单独打包成为一个应用放在单独的Server实例上,其他的应用对其访问来触发相应的定时Job。这样做的好处是方便管理,也可以在一定程度上避免共享资源冲突。

二、ATG定时Job的几个概念:

1、Scheduler组件shcedule模块的核心服务是/atg/dynamo/service/Scheduler组件,该组件负责所有Job的跟踪和触发。该组件的addScheduledJob方法接收一个ScheduledJob结构,来实现对定时Job的注册。

2、ScheduledJob结构:包含了Scheduler所需要所有参数选线的结构类。可参见下文代码。

3、Job组件:需要开发者自定义的组件,一个实现了atg.service.scheduler.Schedulable接口的组件。所有要做的工作都可以放在performScheduledTask实现。

调用/atg/dynamo/service/Scheduler组件的addScheduledJob方法 ,即可将一个Job组件加入到Scheduler中去实现定时触发

以下这段代码示例:一个Job组件包装为ScheduledJob结构传给Scheduler。

ScheduledJob job = new ScheduledJob ("hello",
                                         "Prints Hello",
                                         getAbsoluteName (),
                                         getSchedule (),
                                         ScheduleComponet,
                                         ScheduledJob.SCHEDULER_THREAD);
jobId = getScheduler ().addScheduledJob (job);

注:这一段通常写在Job组件的doStartService方法中(需继承atg.nucleus.GenericService类),用于启动组件时即可定时触发。

4、Task:Job在执行过程中产生的实例,每次触发都会产生一个Task。

Task根据运行线程的位置不同有几种运行模式

(a)SCHEDULER_THREAD:在Scheduler的主线程上直接执行。在执行的过程中其他的定时任务无法执行。因此只适用于耗时较短的Task.

(b)SEPARATE_THREAD:另起一个单独的线程,线程结束后立即销毁。比较适用于那些定时间隔小于完成时间耗时的任务。例如完成一个任务大约需要5分钟。定时间隔设置为3分钟启动一次。

(c)REUSED_THREAD:另起一个单独的线程,任务结束后,任务挂起等待下一次调用。如果任务还在执行过程中,下一次调用又被触发。此时不会新建单独线程。

运行模式是在将job加入Scheduler时传入的,上文代码中ScheduledJob.SCHEDULER_THREAD即是此选项。


5、Schedule :对于定时任务执行时间的描述,即上文代码中的getSchedule ()返回的字符串。ATG中有两种定时方式

(a)按时间间隔:示例如下

schedule=in 30 seconds//在30秒之内执行一次
schedule=every 20 minutes//每20分钟执行一次
(b)按照固定时间:ATG使用以空格分隔的字符串(共计6个描述单位)来表示月、日期、周、每月的第几周、小时、分钟。ATG官方文档对此描述的比较细致,不赘述。只举例如下

schedule=calendar 5 . 2 * * 0//Every Monday in June, every hour on the hour
schedule=calendar * * * * 9-17 30//Every day, between 9am-5pm on the half hour

三、实践篇

1、写一个HelloJob.java类

import atg.nucleus.*;
import atg.service.scheduler.*;

public class HelloJob extends GenericService implements Schedulable
{
  public HelloJob () {}

  // Scheduler property
  Scheduler scheduler;
  public Scheduler getScheduler () { return scheduler; }
  public void setScheduler (Scheduler scheduler)
  { this.scheduler = scheduler; }

// Schedule property
  Schedule schedule;
  public Schedule getSchedule () { return schedule; }
  public void setSchedule (Schedule schedule)
  { this.schedule = schedule; }

  // Schedulable method
  public void performScheduledTask (Scheduler scheduler,
                                    ScheduledJob job)
  { System.out.println ("Hello"); }

  // Start method
  int jobId;
  public void doStartService () throws ServiceException
  {
    ScheduledJob job = new ScheduledJob ("hello",
                                         "Prints Hello",
                                         getAbsoluteName (),
                                         getSchedule (),
                                         this,
                                         ScheduledJob.SCHEDULER_THREAD);
    jobId = getScheduler ().addScheduledJob (job);
  }

  // Stop method
  public void doStopService () throws ServiceException
  {
    getScheduler ().removeScheduledJob (jobId);
  }
}

2、定义helloJob的配置文件,形成组件

$class=HelloJob
$scope=global
scheduler=/atg/dynamo/service/Scheduler
schedule=every 1 minutes

3、定义该Job的启动时机

如果选择随Server启动即启动,则需要找到你应用的Initial.properties(如果没有在你的$ATG_INSTALL_DIR/home/localconfig可以创建一个),文件内容如下:

initialServices+=/test/HelloJob

注:如果采用按钮调用或者其他条件下启动,则需要根据自己的需求来使用代码控制何时触发该Job的注册。

4、打包、启动你的应用

5、访问dyn/admin应用,搜索/atg/dynamo/service/Scheduler即可看到所有Job,其中包含HelloJob

 

四、关于远程调用及SingletonSchedulableService

1、服务器间通信

ATG的应用是多个Module打包成为一个应用,一个应用独占为一个Server实例。原则上,ATG系统中每个应用都可以存在定时Job处理。但是通常情况下,生产环境只会存在一个Schedule服务实例,所有的定时任务都在这个实例上运行,因此很多情况下需要考虑服务间通信的问题。举例来说如果Store应用在用户下单后需要触发一个定时Job来完成某项工作,此时Store服务需要将此项Job注册到Schedule服务上,需要使用远程调用的方式实现,所以开发者在开发时需要明晰各种情况下的调用方式。当然远程调用是另外一个话题,之后再写文探讨。

2、SingletonSchedulableService

继承SingletonSchedulableService 类可以使用ATG提供的定时Job处理单例模式。此单例不是指当前应用下的单例,而是指ATG应用集群下单例模式。这样可以有效的避免多个应用都存在相同的定时job,导致资源冲突。具体细节可参考ATG官方文档。

3、其他

关于定时处理的官方文档可参照:http://docs.oracle.com/cd/E23095_01/Platform.93/ATGProgGuide/html/s0905schedulerservices01.html

posted on 2013-05-04 18:44  阿泰哥  阅读(340)  评论(0编辑  收藏  举报