spring+quartz 기반 분포 식 정시 작업 프레임 워 크 구현
당 사 는 신속히 발전 하 는 창업 회사 로 현재 200 명 이 있 습 니 다.주요 업 무 는 관광 과 호텔 과 관련 된 것 입 니 다.교체 업데이트 주기 가 비교적 빠 르 기 때문에 개발 자 들 은 더 많은 시간 을 들 여 더욱=교체 의 속 도 를 따라 잡 았 고 전체 시스템 에 대한 통제 가 부족 합 니 다.
군집 하기 전에 회사 의 정시 임무 실현 방식 이 없다.
초기 에 응 용 된 방 문 량 이 그리 크 지 않 았 고 한 대의 서버 가 사용 을 완전히 만족 시 켰 으 며 응용 프로그램 에서 정기 적 인 작업 을 수행 해 야 하 는 경우 가 많 았 다.
군집 이 생 긴 후 회사 의 정시 임 무 를 실현 하 는 방식.
사용자 가 증가 함 에 따라 방 문 량 도 증가 하고 한 대의 서버 가 높 은 병행 요 구 를 만족 시 키 지 못 하기 때문에 회 사 는 응용 을 클 러 스 터 에 배치 하고 전단 은 nginx 프 록 시(응용 서버 ip 은 방화벽 으로 격 리 되 어 ip+포트+응용 이름 으로 직접 방문 하 는 방식 을 피 할 수 있 습 니 다).
클 러 스 터 환경 에서 똑 같은 정시 임 무 는 클 러 스 터 에 있 는 모든 기계 에서 실 행 됩 니 다.그러면 정시 임 무 는 반복 적 으로 실 행 됩 니 다.서버 의 부담 을 증가 할 뿐만 아니 라 정시 임 무 를 반복 적 으로 수행 하기 때문에 예상 치 못 한 오 류 를 초래 할 수 있 습 니 다.따라서 회사 의 해결 방안 은 클 러 스 터 의 수량 에 따라자,정시 임무 중의 임 무 를 클 러 스 터 의 모든 기계 에 평균 적 으로 나 누 어 줍 니 다.
현재 군집 중 정시 임무 실현 방식 의 결함
현재 회사 가 클 러 스 터 에서 정시 임 무 를 처리 하 는 방식 은 진정한 분포 식 처리 방식 이 아니 라 가짜 분포 식(회사 내부 에서 흔히 흙 방법 이 라 고 부른다)이다.이런 방식 에 현저 한 결함 이 존재 하 는데 바로 클 러 스 터 에서 기계 가 다운 되면 전체 정시 임 무 를 끊 거나 한꺼번에 다 뛰 지 못 하면 업무 에 심각 한 영향 을 줄 수 있다.
결함 에 대한 해결 방안(본 고의 중점 점)
spring+quartz 를 이용 하여 진정한 분포 식 정시 임무 시스템 을 구축 하고 관련 자 료 를 조회 한 결과 quartz 프레임 워 크 는 원래 분포 식 정시 임 무 를 지원 하 는 것 임 을 알 수 있다.
개발 IDE:Intellij IDEA
JDK 버 전:1.8
Spring 버 전:4.2.6
Quartz 버 전:2.2.1
Spring 과 Quartz 통합 설정
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.aaron.clusterquartz.job"/>
<bean name="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<!-- tomcat -->
<!--<property name="jndiName" value="java:comp/env/jndi/mysql/quartz"/>-->
<!-- jboss -->
<property name="jndiName" value="jdbc/quartz"/>
</bean>
<!-- start -->
<!-- -->
<bean name="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="15"/>
<property name="maxPoolSize" value="25"/>
<property name="queueCapacity" value="100"/>
</bean>
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- -->
<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="configLocation" value="classpath:quartz.properties"/>
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<!-- , -->
<property name="schedulerName" value="baseScheduler"/>
<!-- -->
<property name="overwriteExistingJobs" value="true"/>
<property name="applicationContextSchedulerContextKey" value="appli"/>
<property name="jobFactory">
<bean class="com.aaron.clusterquartz.autowired.AutowiringSpringBeanJobFactory"/>
</property>
<property name="triggers">
<list>
<ref bean="printCurrentTimeScheduler"/>
</list>
</property>
<property name="jobDetails">
<list>
<ref bean="printCurrentTimeJobs"/>
</list>
</property>
<property name="taskExecutor" ref="executor"/>
</bean>
<!-- Job -->
<bean name="printCurrentTimeJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.aaron.clusterquartz.job.PrintCurrentTimeJobs"/>
<!-- spring , scheduler -->
<!--<property name="jobDataAsMap">
<map>
<entry key="clusterQuartz" value="com.aaron.framework.clusterquartz.job.ClusterQuartz"/>
</map>
</property>-->
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean>
<!-- -->
<bean name="printCurrentTimeScheduler" class="com.aaron.clusterquartz.cron.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="printCurrentTimeJobs"/>
<property name="cronExpression">
<value>0/10 * * * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<!-- end -->
</beans>
quartz 속성 파일
#============================================================================
# Configure JobStore
# Using Spring datasource in quartzJobsConfig.xml
# Spring uses LocalDataSourceJobStore extension of JobStoreCMT
#============================================================================
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 5000
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.txIsolationLevelReadCommitted = true
# Change this to match your DB vendor
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#============================================================================
# Configure Main Scheduler Properties
# Needed to manage cluster instances
#============================================================================
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=MY_CLUSTERED_JOB_SCHEDULER
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
관련 클래스 설명AutowiringSpringBeanJobFactory 클래스 는 scheduler 에서 spring 주 해 를 사용 할 수 있 도록 하기 위해 서 입 니 다.주 해 를 사용 하지 않 으 면 이 클래스 를 적용 하지 않 고 직접 사용 할 수 있 습 니 다.
SpringBeanJobFactory
package com.aaron.clusterquartz.autowired;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
/**
* @author
* @description job spring
* @date 2016-05-27
*/
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware
{
private transient AutowireCapableBeanFactory beanFactory;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
beanFactory = applicationContext.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception
{
Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
package com.aaron.clusterquartz.job;
import com.arron.util.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.Date;
/**
* @author
* @description
* @date 2016-05-23
*/
public class PrintCurrentTimeJobs extends QuartzJobBean
{
private static final Log LOG_RECORD = LogFactory.getLog(PrintCurrentTimeJobs.class);
// AutowiringSpringBeanJobFactory @Autowired ,
@Autowired
private ClusterQuartz clusterQuartz;
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException
{
LOG_RECORD.info("begin to execute task," + DateUtils.dateToString(new Date()));
clusterQuartz.printUserInfo();
LOG_RECORD.info("end to execute task," + DateUtils.dateToString(new Date()));
}
}
테스트 결과:컴퓨터 가 한 대 밖 에 없 기 때문에 저 는 8080 과 8888 두 개의 포트 를 열 어 테스트 했 습 니 다.위의 정시 임 무 는 10 초 에 한 번 씩 실 행 됩 니 다.
내 가 8080 포트 를 시작 할 때 콘 솔 이 10 초 마다 문 구 를 인쇄 하 는 것 을 볼 수 있다.
두 포트 가 동시에 시 작 된 비교 테스트 에서 볼 수 있 듯 이 한 포트 만 이 정시 작업 을 하고 있다.
이것 은 정시 작업 을 하고 있 는 포트 를 닫 은 후,이전의 다른 뛰 지 않 은 포트 가 연결 되 기 시작 하여,정시 작업 을 계속 실행 합 니 다.
이로써 우 리 는 분포 식 정시 임무(또는 군집)에서 같은 시간 에 하나의 정시 임무 만 운행 하 는 것 을 똑똑히 볼 수 있다.
전체 demo 주소:http://xiazai.jb51.net/201701/yuanma/spring-cluster-quartz_jb51.rar
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.