티스토리 뷰

Programming/Java

Quartz Web Application

파란크리스마스 2010. 9. 17. 10:18
728x90

출처 : http://journae.springnote.com/pages/6100033



WEB-INF\web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="starter" version="2.4" ...>

 <context-param>
  <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
  <param-value>ApplicationResources</param-value>
 </context-param>

 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext.xml</param-value>
 </context-param>

 <context-param>
  <param-name>webAppRootKey</param-name>
  <param-value>quartz.root</param-value>
 </context-param>

 <context-param>
  <param-name>log4jConfigLocation</param-name>
  <param-value>classpath:log4j.xml</param-value>
 </context-param>

 <filter>
  <filter-name>action2-cleanup</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
 </filter>

 <filter>
  <filter-name>sitemesh</filter-name>
  <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
 </filter>

 <filter>
  <filter-name>sitemesh-freemarker</filter-name>
  <filter-class>org.apache.struts2.sitemesh.FreeMarkerPageFilter</filter-class>
 </filter>

 <filter>
  <filter-name>action2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>action2-cleanup</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 <filter-mapping>
  <filter-name>sitemesh-freemarker</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 <filter-mapping>
  <filter-name>action2</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <!-- Listeners -->
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

 <listener>
  <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
 </listener>

 <servlet>
  <servlet-name>freemarker</servlet-name>
  <servlet-class>com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet</servlet-class>
 </servlet>

 <servlet>
  <servlet-name>DefinitionInitializer</servlet-name>
  <servlet-class>org.quartz.ui.web.init.DefinitionInitializer</servlet-class>
  <init-param>
   <param-name>definition-file</param-name>
   <param-value>(PATH_TO_DEFINITIONS_FILE)</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <!-- Servlets -->
 <servlet>
  <servlet-name>jspSupportServlet</servlet-name>
  <servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
  <load-on-startup>5</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>freemarker</servlet-name>
  <url-pattern>*.ftl</url-pattern>
 </servlet-mapping>

 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>

 </web-app>

WEB-INF\classes\applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans ...>

 <bean id="authenticator" class="org.quartz.ui.web.security.SimpleAuthenticator">
  <property name="username">
   <value>quartz</value>
  </property>
  <property name="password">
   <value>quartz</value>
  </property>
 </bean>

 <bean id="logonAction" class="org.quartz.ui.web.action.LogonAction" scope="prototype">
  <property name="authenticator" ref="authenticator" />
 </bean>

 <bean id="quartzUser" class="org.quartz.ui.web.security.User">
  <property name="username"><value>quartz</value></property>
  <property name="password"><value>quartz</value></property>
  <property name="roles">
  <map>
   <entry key="manager">
    <value>manager</value>
   </entry>
  </map>
  </property>
 </bean>

 <bean id="users" class="org.quartz.ui.web.security.Users">
  <property name="userMap">
  <map>
   <entry key="quartz">
    <ref bean="quartzUser"/>
   </entry>
  </map>
  </property>
 </bean>

</beans>

WEB-INF\classes\quartz.properties

#============================================================================
# Configure Main Scheduler Properties 
#============================================================================

 
org.quartz.scheduler.instanceName = TestScheduler
org.quartz.scheduler.instanceId = AUTO
 
#============================================================================
# Configure ThreadPool 
#============================================================================

 
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 4
 
#============================================================================
# Configure JobStore 
#============================================================================

 
org.quartz.jobStore.misfireThreshold = 60000
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
##org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
#org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate

org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = true
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix = QRTZ_

org.quartz.jobStore.isClustered= true
org.quartz.jobStore.clusterCheckinInterval= 20000
 
#============================================================================
# Configure Datasources 
#============================================================================


org.quartz.dataSource.myDS.driver=com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:5141/batch
org.quartz.dataSource.myDS.user=root
org.quartz.dataSource.myDS.password=

#org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
#org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@polarbear:1521:dev
#org.quartz.dataSource.myDS.user = quartz
#org.quartz.dataSource.myDS.password = quartz
#org.quartz.dataSource.myDS.maxConnections = 5

 
#org.quartz.dataSource.myDS.driver = org.postgresql.Driver
#org.quartz.dataSource.myDS.URL = jdbc:postgresql:dev
#org.quartz.dataSource.myDS.user = jhouse
#org.quartz.dataSource.myDS.password =
#org.quartz.dataSource.myDS.maxConnections = 5

 
#============================================================================
# Configure Plugins
#============================================================================

 
#*  org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin

#*  org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin
#*  # init plugin will load jobs.xml as a classpath resource i.e. /jobs.xml if not found on file system
#*  org.quartz.plugin.jobInitializer.fileNames=jobs.xml
#*  org.quartz.plugin.jobInitializer.overWriteExistingJobs = false
#*  org.quartz.plugin.jobInitializer.failOnFileNotFound = false
#*  org.quartz.plugin.jobInitializer.scanInterval = 30
#*  # org.quartz.plugin.jobInitializer.wrapInUserTransaction = true

#*  org.quartz.plugin.jobInitializerMultiple.class = org.quartz.plugins.xml.JobInitializationPlugin
#*  # init plugin will load jobs.xml as a classpath resource i.e. /jobs.xml and jobs2.xml if not found on file system
#*  org.quartz.plugin.jobInitializerMultiple.fileNames=jobs2.xml,jobs3.xml
#*  org.quartz.plugin.jobInitializerMultiple.overWriteExistingJobs = false
#*  org.quartz.plugin.jobInitializerMultiple.failOnFileNotFound = false
#*  # org.quartz.plugin.jobInitializerMultiple.wrapInUserTransaction = true

quartz.properties 환경 파일 로딩 순서

org.quartz.ui.web.init.DefinitionInitializer.init
  |
  org.quartz.ee.servlet.QuartzInitializerServlet.init
    |
    org.quartz.impl.StdSchedulerFactory.getScheduler
      |
      org.quartz.impl.StdSchedulerFactory
        initialize() 메소드에서 quartz.properties 파일 로딩

DB의 설정된 Job을 조회 하여 등록하는 순서

org.quartz.simpl.SimpleThreadPool$WorkerThread.run
  |
  org.quartz.core.JobRunShell.run
    |
    org.quartz.jobs.FileScanJob.execute
      |
      org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveTrigger
        |
        org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectTrigger

StdJDBCDelegate의 selectTrigger 메소드

package org.quartz.impl.jdbcjobstore;

public class StdJDBCDelegate implements DriverDelegate, StdJDBCConstants {

    public Trigger selectTrigger(Connection conn, String triggerName,
            String groupName) throws SQLException, ClassNotFoundException,
            IOException {

        try {
            Trigger trigger = null;

            ps = conn.prepareStatement(rtp(SELECT_TRIGGER));
            rs = ps.executeQuery();

                if (triggerType.equals(TTYPE_SIMPLE)) {
                    ps = conn.prepareStatement(rtp(SELECT_SIMPLE_TRIGGER));

                    if (rs.next()) {
                        SimpleTrigger st = new SimpleTrigger(triggerName,
                                groupName, jobName, jobGroup, startTimeD,
                                endTimeD, repeatCount, repeatInterval);

                        if (null != map) {
                            st.setJobDataMap(new JobDataMap(map));
                        }
                        trigger = st;
                    }
                } else if (triggerType.equals(TTYPE_CRON)) {
                    ps = conn.prepareStatement(rtp(SELECT_CRON_TRIGGER));

                    CronTrigger ct = new CronTrigger(triggerName, groupName,
                                    jobName, jobGroup, startTimeD, endTimeD,
                                    cronExpr, timeZone);
                    if (null != map) {
                        ct.setJobDataMap(new JobDataMap(map));
                    }
                    trigger = ct;

                } else if (triggerType.equals(TTYPE_BLOB)) {
                    ....
                } else {
                    throw new ClassNotFoundException("class for trigger type '"
                            + triggerType + "' not found.");
                }
            }

            return trigger;
        } finally {
            closeResultSet(rs);
            closeStatement(ps);
        }
    }

Cluster 관련 내용

org.quartz.impl.jdbcjobstore.JobStoreSupport

public abstract class JobStoreSupport implements JobStore, Constants {

    protected boolean doCheckin() throws JobPersistenceException {
        failedRecords = clusterCheckIn(conn);
    }

    class ClusterManager extends Thread {
        private boolean manage() {
            res = doCheckin();
            return res;
        }

        public void run() {
            while (!shutdown) {

                if (!shutdown) {
                    long timeToSleep = getClusterCheckinInterval();
                    timeToSleep = Math.max(getDbRetryInterval(), timeToSleep);
                    Thread.sleep(timeToSleep);
                    this.manage()) {
                }

            }//while !shutdown
        }
    }
}

- end -

댓글
300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함