1. 석영 작업 스케줄링의 기본 구현 원리
Quartz는 OpenSymphony의 작업 스케줄링 분야의 오픈 소스 프로젝트로 Java 구현을 기반으로합니다. 우수한 오픈 소스 스케줄링 프레임 워크로서 Quartz는 다음과 같은 기능이 있습니다.
(1) 다양한 스케줄링 방법을 지원하는 것과 같은 강력한 스케줄링 기능은 다양한 기존 및 특별한 요구를 충족시킬 수 있습니다.
(2) 다중 작업 조합 및 스케줄링을 지원하고 데이터 예약의 여러 저장 방법을 지원하는 것과 같은 유연한 응용 방법;
(3) 분산 및 클러스터링 기능 인 Terracotta는 획득 후 원래 기능을 더욱 향상 시켰습니다. 이 기사는이 부분에 추가됩니다.
1.1 석영 코어 요소
Quartz 작업 스케줄링의 핵심 요소는 스케줄러 작업 스케줄러, 트리거 트리거 및 작업 작업입니다. 트리거 및 작업이 작업 일정을위한 메타 데이터 인 경우, 스케줄러는 실제로 스케줄링을 수행하는 컨트롤러입니다.
트리거는 스케줄링 시간을 정의하는 데 사용되는 요소, 즉 시간 규칙에 따라 작업이 실행됩니다. Quartz에는 Simpletrigger, Crontirgger, Date Intervaltrigger 및 NthincludedDaytrigger의 네 가지 유형의 트리거가 있습니다. 이 네 가지 트리거는 엔터프라이즈 응용 프로그램의 대부분의 요구를 충족시킬 수 있습니다.
작업은 예정된 작업을 나타내는 데 사용됩니다. 주로 두 가지 유형의 작업이 있습니다 : 무국적 및 상태. 동일한 방아쇠의 경우, 상태의 직무를 병렬로 실행할 수 없습니다. 작업이 트리거 된 후에 만 마지막으로 실행 된 후에야 다음 실행이 트리거 될 수 있습니다. 작업은 휘발성과 내구성이있는 두 가지 주요 속성을 가지고 있습니다. 여기서 휘발성은 작업이 데이터베이스 저장소에 지속되는지 여부를 의미하는 반면 내구성은 트리거 연관이 없을 때 작업이 유지되는지 여부를 의미합니다. 둘 다 값이 참을 때 지속되거나 보존됩니다. 작업은 여러 트리거와 관련 될 수 있지만 트리거는 하나의 작업 만 연결할 수 있습니다.
스케줄러는 Scheduler Factory : DirectSchedulerFactory 또는 StdSchedulerFactory에 의해 작성됩니다. DirectSchedulerFactory가 사용하기에 충분히 편리하지 않으며 많은 세부 수동 코딩 설정이 필요하기 때문에 두 번째 공장 인 StdSchedulerFactory는 더 자주 사용됩니다. 스케줄러의 세 가지 주요 유형이 있습니다 : Remotembeanscheduler, Remotescheduler 및 Stdscheduler.
석영의 핵심 요소 사이의 관계는 그림 1.1에 나와 있습니다.
그림 1.1 핵심 요소 관계 다이어그램
1.2 석영 스레드보기
석영에는 두 가지 유형의 스레드, 스케줄러 스케줄러 스레드 및 작업 실행 스레드가 있으며 작업 실행 스레드는 일반적으로 스레드 풀을 사용하여 스레드 그룹을 유지합니다.
그림 1.2 석영 스레드보기
스케줄러에는 두 가지 기본 스레드가 있습니다 : 정기적 인 스케줄링을 수행하는 스레드와 잘못된 트리거를 실행하는 스레드. 정기적 인 디스패치 스레드는 저장된 모든 트리거를 폴링합니다. 트리거 해야하는 트리거가있는 경우, 즉 다음 트리거의 시간에 도달 한 시간이 있으면 작업 실행 스레드 풀에서 유휴 스레드를 얻어 트리거와 관련된 작업을 실행합니다. 잘못된 스레드는 모든 트리거를 스캔하여 잘못된 트리거가 있는지 확인합니다. 그렇다면, 그것은 잘못된 정책에 따라 별도로 처리됩니다 (지금 화재 또는 다음 화재를 기다리십시오).
1.3 쿼츠 작업 데이터 저장
석영의 트리거와 작업은 사용하기 전에 보관해야합니다. Quartz에는 Ramjobstore와 JobstoresUpport의 두 가지 저장 방법이 있습니다. Ramjobstore는 메모리에 트리거 및 작업을 저장하는 반면 JobstoresUpport는 JDBC를 기반으로 데이터베이스의 트리거 및 작업을 저장합니다. Ramjobstore는 매우 빠른 액세스이지만 시스템이 중지 된 후에 모든 데이터가 손실되므로 Cluster 응용 프로그램에서 JobstoresUpport를 사용해야합니다.
2. 쿼츠 클러스터 원리 2.1 석영 클러스터 아키텍처
석영 클러스터의 각 노드는 독립 석영 응용 프로그램으로, 다른 노드를 관리합니다. 즉, 각 노드를 별도로 시작하거나 중지해야합니다. 석영 클러스터에서 독립 쿼츠 노드는 다른 노드 또는 관리 노드와 통신하지 않고 그림 2.1과 같이 동일한 데이터베이스 테이블을 통해 다른 석영 응용 프로그램을 인식합니다.
그림 2.1 석영 클러스터 아키텍처
2.2 석영 클러스터 관련 데이터베이스 테이블
석영 클러스터는 데이터베이스에 따라 달라 지므로 먼저 석영 데이터베이스 테이블을 만들어야합니다. Quartz 릴리스 패키지에는 지원되는 모든 데이터베이스 플랫폼에 대한 SQL 스크립트가 포함되어 있습니다. 이 SQL 스크립트는 <quartz_home>/docs/dbtables 디렉토리에 저장됩니다. 여기에 사용 된 석영 버전 1.8.4에는 총 12 개의 테이블이 있습니다. 테이블 수는 버전에서 다를 수 있습니다. 데이터베이스는 MySQL이며 tables_mysql.sql을 사용하여 데이터베이스 테이블을 만듭니다. 모든 테이블은 그림 2.2에 나와 있으며이 테이블에 대한 간단한 소개는 그림 2.3에 나와 있습니다.
그림 2.2 MySQL 데이터베이스에서 쿼츠 1.8.4에서 생성 된 테이블
그림 2.3 석영 데이터 테이블 소개
2.2.1 스케줄러 상태 테이블 (QRTZ_SCHEDULER_STATE)
설명 : 클러스터의 노드 인스턴스 정보 인 Quartz는 클러스터의 각 인스턴스의 현재 상태를 결정하기 위해이 테이블의 정보를 정기적으로 읽습니다.
instance_name : 구성 파일의 org.quartz.scheduler.instanceid로 구성된 이름입니다. Auto로 설정되면 Quartz는 실제 기계 이름과 현재 시간을 기준으로 이름을 생성합니다.
last_checkin_time : 마지막 체크인 시간
Checkin_Interval : 체크인 간격 시간
2.2.2 트리거 및 작업 협회 테이블 (qrtz_fired_triggers)
관련 작업의 트리거 트리거 및 실행 정보와 관련된 상태 정보를 저장합니다.
2.2.3 트리거 정보 테이블 (qrtz_triggers)
trigger_name : 트리거 이름, 사용자는 강제 요구 사항 없음, 사용자를 의지하여 이름을 사용자 정의 할 수 있습니다.
Trigger_Group : 사용자가 마음대로 사용자 정의 할 수있는 트리거 그룹의 이름이며 강제 요구 사항이 없습니다.
job_name : qrtz_job_details table job_name의 외국 키
job_group : qrtz_job_details table job_group 이외 키
trigger_state : 현재 트리거 상태가 획득되도록 설정되었습니다. 대기로 설정되면 작업이 트리거되지 않습니다.
trigger_cron : cron 표현식을 사용하여 트리거 유형
2.2.4 작업 세부 사항 테이블 (qrtz_job_details)
참고 : 작업 세부 사항을 저장하면 실제 상황에 따라 사용자가 테이블을 초기화해야합니다.
job_name : 클러스터의 작업 이름. 사용자는 강제 요구 사항없이 이름을 마음대로 사용자 정의 할 수 있습니다.
JOB_GROUP : 작업이 클러스터에 속하는 그룹의 이름이며, 이는 사용자가 마음대로 사용자 정의하며 강제 요구 사항이 없습니다.
job_class_name : 클러스터의 작업 구현 클래스의 전체 패키지 이름입니다. 석영은 클래스 경로로가는 경로를 기반으로 구인을 찾습니다.
IS_DURABLE : 지속 여부,이 속성을 1로 설정하면 Quartz는 작업을 데이터베이스에 유지합니다.
JOB_DATA : 유지 된 작업 개체를 저장하는 Blob 필드.
2.2.5 권한 정보 표 (qrtz_locks)
참고 : 그림 2.4와 같이 tables_oracle.sql에는 해당 DML 초기화가 있습니다.
그림 2.4 석영 권한 정보 표에서 초기화 정보
2.3 쿼츠 스케줄러 시작 프로세스 클러스터
석영 스케줄러 자체는 클러스터링되어 있음을 알지 못하며 스케줄러에 대해 구성된 JDBC 작업장 만 알고 있습니다. 석영 스케줄러가 시작되면 Jobstore의 Schedulerstarted () 메소드를 호출하여 Jobstore 스케줄러에게 시작된 것을 알려줍니다. schedulerstarted () 메소드는 JobStoresUpport 클래스에서 구현됩니다. JobStoresUpport 클래스는 Quartz.Properties 파일의 설정을 기반으로 스케줄러 인스턴스가 클러스터에 참여하는지 여부를 결정합니다. 클러스터가 구성되면 새 ClusterManager 클래스의 인스턴스가 생성, 초기화 및 시작됩니다. ClusterManager는 JobStoresUpport 클래스의 인라인 클래스이며 Java.lang.thread를 상속 받으면 정기적으로 실행되며 스케줄러 인스턴스에서 체크인 기능을 수행합니다. 스케줄러는 또한 다른 클러스터 노드가 실패했는지 확인해야합니다. 체크인 작업 실행 사이클은 Quartz.properties에서 구성됩니다.
2.4 실패한 스케줄러 노드 감지
스케줄러 인스턴스가 체크인을 수행하면 예상시 다른 스케줄러 인스턴스가 체크인되지 않았는지 확인합니다. 이것은 Scheduler_state 테이블의 Last_chedk_time 열에서 기록 된 스케줄러의 값이 org.quartz.jobstore.clustercheckininterval보다 초기인지 확인하여 결정됩니다. 미리 결정된 시간에 하나 이상의 노드가 체크인되지 않은 경우, 실행중인 스케줄러는 실패했다고 가정합니다.
2.5 실패한 인스턴스에서 작업 복구
작업을 실행할 때 셰더 인스턴스가 실패하면 다른 작업 스케줄러 인스턴스가 작업을 수행하여 다시 실행할 수 있습니다. 이 동작을 달성하려면 JobDetail 객체로 구성된 작업 복구 속성을 true (job.setRequestSrecovery (true))로 설정해야합니다. 복구 가능한 속성이 False로 설정된 경우 (기본값은 False) 스케줄러가 작업을 실행하지 못하면 재실행되지 않습니다. 다음 트리거 시간에 다른 스케줄러 인스턴스에 의해 트리거됩니다. 실패 후 스케줄러 인스턴스가 얼마나 빨리 감지 될 수 있는지는 각 스케줄러의 체크인 간격 (예 : org.quartz.jobstore.clustercheckininterval)에 따라 얼마나 빨리 감지 될 수 있는지.
3. 석영 클러스터 인스턴스 (Quartz+Spring)
3.1 스프링 쿼츠 문제와 호환되지 않습니다
스프링은 2.0.2 이후 더 이상 석영을 지원하지 않습니다. 구체적으로, Quartz+Spring이 Quartz의 작업을 데이터베이스에 인스턴셔션하면 일련의 오류가 발생합니다.
<bean id = "jobtask"> <property name = "targetObject"> <ref bean = "QuartzJob"/> </property> <속성 이름 = "targetMethod"> value "
MethodInVokingJobdetailFactoryBean 클래스의 MethodInvoking 메소드는 직렬화를 지원하지 않으므로 쿼츠 작업을 데이터베이스에 직렬화 할 때 오류가 발생합니다.
먼저, MethodInvokingJobdetailFactoryBean의 문제를 해결하십시오. Spring 소스 코드를 수정하지 않으면이 클래스 사용을 피하고 직접 JobDetail을 호출 할 수 있습니다. 그러나 JobDetail 구현을 사용하려면 직접 Mothodinvoking의 논리를 구현해야합니다. JobClass 및 JobDataasmap 속성을 사용하여 JobDetail의 속성을 사용하여 공장 (관리자)을 사용자 정의하여 동일한 목적을 달성 할 수 있습니다. 예를 들어이 예에서는이 기능을 구현하기 위해 새로운 MyDetailquartzjobbean이 작성되었습니다.
3.2 MyDetailquartzjobbean.java 파일
패키지 org.lxh.mvc.jobbean; import java.lang.reflect.method; import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; import org.quartz.jobexecutioncontext; import org.quartz.jobexecutionExemention; org.springframework.context.applicationcontext; import org.springframework.scheduling.quartz.quartzjobbean; public class mydetailquartzjobbean quartzjobbean {보호 된 최종 logger = logfactory.getlog (getClass ()); 개인 문자열 targetObject; 개인 문자열 targetMethod; Private ApplicationContext CTX; 보호 된 void executeInternal (jobExecutionContext Context)은 JobExecutionException {try {logger.info ( "execute [" + targetObject + "]를 한 번에 >>>>"); Object OargetObject = ctx.getBean (TargetObject); 메소드 m = null; try {m = oArgetObject.getClass (). getMethod (targetMethod, new Class [] {}); M.Invoke (OargetObject, new Object [] {}); } catch (SecurityException e) {logger.error (e); } catch (nosuchmethodexception e) {logger.error (e); }} catch (예외 e) {throw new jobExecutionException (e); }} public void setApplicationContext (ApplicationContext ApplicationContext) {this.ctx = ApplicationContext; } public void settargetObject (String targetObject) {this.targetObject = targetObject; } public void settArgetMethod (String targetMethod) {this.targetMethod = TargetMethod; }}3.3 실제 작업 구현 클래스
테스트 클래스에서는 시스템의 현재 시간을 인쇄하는 기능이 간단하게 구현됩니다.
패키지 org.lxh.mvc.job; import java.io.serializable; import java.util.date; import org.apache.commons.log; import org.apache.commons.logging.logactory; private logger = logfactory.ggetlog (clest.ggets); 개인 정적 최종 최종 긴 SerialversionUID = -2073310586499744415L; public void execute () {date date = new Date (); System.out.println (date.tolocalestring ()); }}3.4 Quartz.xml 파일을 구성하십시오
<bean id = "test"scope = "프로토 타입"> </bean> <bean id = "testjobtask"> <property name = "jobClass"> <value> org.lxh.mvc.jobbean.mydetailquartzjobbean </value> <property name = "jobdataasmap"> <Entry Key = "value" "test"///>. key = "targetMethod"value = "execute"/> </map> </property> </bean> <bean name = "testtrigger"> <property name = "jobDetail"ref = "testjobtask"/> <property name = "cronexpression"value = "0/1 * * * *?" /> </bean> <bean id = "quartzscheduler"> <속성 이름 = "configlocation"value = "classPath : Quartz.Properties"/> <property name = "triggers"> <list> <ref bean = "reftrigger"/</list> </list> </list> </list> </list> </list> </list> </list> </list> <property name = "applactContexTchedulerContextKey" "ApplicateContext" "
3.5 테스트
Servera 및 ServerB의 코드 및 구성은 정확히 동일합니다. 먼저 Servera를 시작한 다음 ServerB를 시작하십시오. 서버가 종료되면 ServerB는 종료를 모니터링하고 Servera에서 실행중인 작업을 인수하고 실행을 계속합니다.
4. 쿼츠 클러스터 인스턴스 (단일 석영)
Spring+Quartz의 클러스터 구성을 구현했지만 Spring과 Quartz의 호환성 문제로 인해이 방법을 사용하는 것이 좋습니다. 이 섹션에서는 Spring+Quartz에 비해 간단하고 안정적 인 Quartz와 별도로 구성된 클러스터를 구현했습니다.
4.1 엔지니어링 구조
우리는 Quartz 만 사용하여 클러스터 기능, 코드 구조 및 그림 3.1과 같이 제 3 자 JAR 패키지를 구현합니다. 그 중에서 MySQL 버전 : 5.1.52 및 MySQL 드라이버 버전 : MySQL-Connector-Java-5.1.5-Bin.jar (5.1.52의 경우 일부 MySQL 드라이버와 결합 할 때 정상적으로 실행할 수없는 버그가 있기 때문에이 버전의 드라이버를 사용하는 것이 좋습니다).
그림 4.1 석영 클러스터 엔지니어링 구조 및 필요한 타사 JAR 패키지
그중에서도 Quartz.properties는 Quartz 구성 파일이며 SRC 디렉토리에 배치됩니다. 그러한 파일이 없으면 Quartz는 Quartz.properties 파일을 JAR 패키지에 자동으로로드합니다. Simplerecoveryjob.java 및 Simplerecoverystatefuljob.java는 두 가지 작업입니다. Clusterexample.java는 스케줄링 정보, 메커니즘 트리거 및 해당 테스트 메인 기능을 작성합니다.
4.2 구성 파일 quartz.properties
기본 파일 이름 Quartz.properties는 "org.quartz.jobstore.isclusted"속성을 "true"로 설정하여 클러스터 기능을 활성화하는 데 사용됩니다. 클러스터의 각 인스턴스에는 고유 한 "인스턴스 ID"( "org.quartz.scheduler.instanceId"속성)이 있어야하지만 동일한 "스케줄러 인스턴스 이름"( "org.quartz.scheduler.instanceName")을 가져야합니다. 이는 클러스터의 각 인스턴스가 동일한 Quartz.properperations Constigurations Constigraturation 구성 파일을 사용해야합니다. 다음 예외를 제외하고 구성 파일의 내용은 동일해야합니다.
에이. 스레드 풀 크기.
비. 다른 "org.quartz.scheduler.instanceid"속성 값 ( "자동"으로 설정).
#========================================================================== =========================================================================== =========================================================================== =========================================================================== =========================================================================== =========================================================================== =========================================================================== =========================================================================== Auto#============================================================================================================================================================== ============================================================================================================= org.quartz.jobstore.impl.jdbcjobstore.jobstoretxorg.quartz.jobstore.driverdelegateclass = org.quartz.impl.jdbcjobstore.stdjdbcdelegateorg.quartz.jobstore.tableprefix = qrtz_org.ibstored = trueorg.quartz.jobstore.clustercheckininterval = 10000 org.quartz.jobstore.datasource = myds #===================================================================================================================================== ========================================================================================================================================= ========================================================================================================================================= ========================================================================================================================================= #=========================================================================================== com.mysql.jdbc.driverorg.quartz.datasource.myds.url = jdbc : mysql : //192.168.31.18 : 3306/test? useunicode = true & charac 123456org.quartz.datasource.myds.maxConnections = 30#=========================================================== ================================================================= ================================================================= ================================================================= ================================================================= ================================================================= ================================================================= ================================================================= org.quartz.simpl.simplethreadpoolorg.quartz.threadpool.threadcount = 5org.quartz.threadpool.threadpriority = 5org.quartz.threadpool.threadsinheritContextClassLoaderOfinitializationThread = true
4.3 ClusterExample.java 파일
패키지 클러스터; import java.util.date; import org.quartz.jobdetail; import org.quartz.scheduler; import org.quartz.schedulerfactory; import org.quartz.simpletrigger; import org.quartz.impl.stdschedulerfactory; public void void cluber (schelure) 예외 {System.out.println ( "**** 기존 작업/트리거 삭제 *****"); // UnSchedule jobs String [] groups = inscheduler.getTriggerGroupNames (); for (int i = 0; i <groups.length; i ++) {string [] names = inscheduler.gettriggerNames (Groups [i]); for (int j = 0; }} // 작업 삭제 그룹 = inscheduler.getJobgroupNames (); for (int i = 0; i <groups.length; i ++) {string [] names = inscheduler.getJobnames (groups [i]); for (int J = 0; }}} public void run (부울 경사, 부울 inschedulejobs) 예외 {// 먼저 스케줄러 schedulerfactory sf = new stdschedulerfactory ()에 대한 참조를 받아야합니다. 스케줄러 일정 = sf.getScheduler (); if (toncearjobs) {cleanup (일정); } system.out.println ( "------------------------------------------------ if (inschedulejobs) { System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Scheduler가 내려 갔을 때이 작업을 다시 시작하십시오 at : " + trigger.getNextFireTime () +"및 반복 : " + trigger.getRepeatCount () +"Times, Every " + trigger.getRigge.getRiger.getRepeatInterVal () / 1000 +"seconds "); Sched.ScheduleJob (job = new jobDetail ("job_ " + Count, Schedid, SimereCoveroVeWovere, ordecoWoryWovery, ord) Scheduler는 Scheduler가 내려 갔을 때 진행중인 경우 ... SetRightsRecovery (false) = "TRIG_" + COUNT, SEALLID, 100, 2000L; " + trigger.getNextFireTime () +"및 반복 : " + trigger.getRepeatCount () +"times, 모든 " + trigger.getRigge.getRiger.getRepeatInterVal () / 1000 +"seconds "); Sched.ScheduleJob (작업, 트리거);} // 작업이 시작되지 않을 때까지 시작되지 않습니다. System.out.println ( "------------------------------------------ System.out.println("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Thread.sleep(3600L * 1000l)} catch (예외 e) {} System.out.println("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- args.length; if [i] .equalsignorecase ( "clearjobs") {aregs [i] .equalsignorecase ( "dontschedulejobs") {schedulejobs}} }}4.4 Simplerecoveryjob.java
패키지 클러스터; import java.io.serializable; import java.util.date; import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; import org.quartz.job; import org.quartz.jobexectontxt; import org.quartz.jobecution incations, joctecution and jortecution incation; 반복적으로 실행하고, 실행 메소드에서 관련 코드를 작성하고 싶다는 전제는 다음과 같습니다. SimpleJob 클래스가 인스턴스화 될 때와 실행 방법을 호출 할 때 작업 인터페이스 구현 // 우리는 이에주의를 기울일 필요가 없으며 QuartzPublic 클래스를 간단하게 남겨 둘 필요가 없습니다. logfactory.getLog (simplerecoveryjob.class); public simplerecoveryjob () {} public void execute (jobExecutionContext Context) jobExecutionException {//이 작업은 단순히 작업 이름을 인쇄하는 것입니다. System.out.println ( "작업 111111111111111111 SimplerecoveryJob :" + jobName + "" + new date ()); }}4.5 작동 결과
서버 A 및 서버 B의 구성 및 코드는 정확히 동일합니다. 실행 방법 : clusterexample.java 모든 호스트에서 작업을 일정에 추가하고 실행 결과를 관찰하십시오.
RUN SERVERA, 결과는 그림 4.2에 나와 있습니다.
그림 4.2 Servera 작동 결과 1
ServerB를 켜면 Servera 및 ServerB의 출력이 그림 4.3 및 4.4에 표시됩니다.
그림 4.3 Servera 실행 결과 2
그림 4.4 ServerB 작동 결과 1
ServerB가 켜진 후 시스템은 균형에 대한 책임을 자동으로 인식하고 ServerB가 Job1을 인수한다는 그림 4.3 및 4.4에서 볼 수 있습니다. Servera를 종료 한 후 ServerB의 실행 결과가 그림 4.5에 나와 있습니다.
그림 4.5 ServerB 작동 결과 2
그림 4.5에서 알 수 있듯이 ServerB는 Servera가 손실되었음을 감지하고 작업 작업 2를 인계 하며이 예외 시간 동안 실행 해야하는 job2로 Servera를 잃을 수 있습니다.
5. 주목할만한 것들
5.1 시간 동기화 문제
Quartz는 실제로 동일하거나 다른 기계에서 노드를 실행하는지 상관하지 않습니다. 클러스터가 다른 기계에 배치되면 수평 클러스터라고합니다. 노드가 같은 컴퓨터에서 실행되면 수직 클러스터라고합니다. 수직 클러스터의 경우 단일 고장 지점의 문제가 있습니다. 기계가 충돌하면 모든 노드가 종료되기 때문에 고 가용성 애플리케이션에는 용납 할 수 없습니다. 수평 클러스터의 경우 시간 동기화 문제가 있습니다.
노드는 타임 스탬프를 사용하여 다른 인스턴스에 자체 마지막 체크인 시간을 알립니다. 노드의 시계가 향후 시간으로 설정되면 실행중인 스케줄러는 더 이상 노드가 떨어 졌다는 것을 인식하지 못합니다. 반면에, 노드의 시계가 지난 시간으로 설정되면 다른 노드가 노드가 빠져 나와 작업을 수행하고 재실행을 시도 할 것입니다. 컴퓨터 클럭을 동기화하는 가장 쉬운 방법은 인터넷 시간 서버를 사용하는 것입니다.
5.2 작업을 위해 경쟁하는 노드의 문제
Quartz는 임의의로드 밸런싱 알고리즘을 사용하기 때문에 작업은 다른 인스턴스에 의해 임의의 방식으로 실행됩니다. Quartz의 공식 웹 사이트는 현재 클러스터의 특정 노드에 작업을 할당하는 방법이 없다고 언급했습니다.
5.3 클러스터에서 작업 목록을 얻는 데 문제가 있습니다
현재 데이터베이스 쿼리를 직접 입력하지 않으면 클러스터에서 모든 실행 작업 목록을 얻는 간단한 방법이 없습니다. 스케줄러 인스턴스를 요청하면 해당 인스턴스에서 실행되는 작업 목록 만 얻을 수 있습니다. Quartz 공식 웹 사이트에서는 데이터베이스에 액세스하기 위해 JDBC 코드를 작성하여 해당 테이블에서 모든 작업 정보를 얻을 수 있다고 권장합니다.
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.