머리말
고 가용성과 응용 프로그램의 높은 동시성을 보장하기 위해 여러 노드가 일반적으로 배포됩니다. 타이밍 작업의 경우 각 노드가 자체 타이밍 작업을 수행하면 한편으로는 시스템 리소스를 소비합니다.
반면에 일부 작업이 여러 번 실행되므로 응용 프로그램 논리 문제가 발생할 수 있으므로 타이밍 작업을 수행하기 위해 각 노드를 조정하려면 분산 예약 시스템이 필요합니다.
봄은 석영을 통합합니다
Quartz는 성숙한 작업 스케줄링 시스템입니다. 스프링은 쉽게 개발하기 위해 석영과 호환됩니다. 통합하는 방법을 살펴 보겠습니다.
1. Maven 종속성 파일
<pectionies> <pectinement> <groupId> org.springframework </groupid> <artifactid> 스프링 코어 </artifactid> <버전> 4.3.5. Release </version> </depectency> <groupID> org.springframework </groupid> <artifactId> spring-context-support </artifactid> 4.3.5.3.5.3.5.3.5.3.renease>. </의존성> <pectionency> <groupId> org.springframework </groupid> <artifactid> spring-tx </artifactid> <버전> 4.3.5. release </version> </fectionency> <groupID> org.springframework </groupid> spring-jdbc </artifactid> <version 4.3.5.3.5.3.5.20. <pectionency> <groupid> org.quartz-scheduler </groupid> <artifactid> quartz </artifactid> <bersion> 2.2.3 </version> </dependency> <groupId> mysql </groupid> <atifactid> mySQL-connector-java </artifactid> </version> 5.1.29 </의존성>
주요 것은 스프링 관련 라이브러리, 석영 라이브러리 및 MySQL 드라이버 라이브러리입니다. 참고 : 분산 예약은 데이터베이스 사용이 필요하며 MySQL은 여기에서 선택됩니다.
2. 작업 구성
작업을 구성하는 방법에는 두 가지가 있습니다.
2.1methodinvokingjobdetailfactorybean
특정 콩의 메소드를 호출하려면 특정 구성은 다음과 같습니다.
<bean id = "FirstTask"> <property name = "targetObject"ref = "FirstService" /> <property name = "targetMethod"value = "service" /> < /bea>
2.2JOBDETAILFACTORYBEAN
이 방법은 더 유연하며 다음과 같이 전달 매개 변수를 설정할 수 있습니다.
<bean id = "FirstTask"> <property name = "jobClass"value = "zh.maven.squartz.task.firsttask"/> <property name = "jobDatamap"> <map> <Entry Key = "FirstService"value-Ref = "FirstService"/> </property> </ban>
JobClass에 의해 정의 된 작업 클래스는 쿼츠 조브를 상속하고 ExecuteInternal 메소드를 구현합니다. JobDatamap은 데이터를 작업에 전달하는 데 사용됩니다
3. 스케줄링에 사용되는 트리거를 구성하십시오
두 가지 트리거 유형이 제공됩니다 : SimpletriggerFactoryBean 및 CrontriggerFactoryBean
CrontriggerFactoryBean에 중점을두면이 유형은 다음과 같이 더 유연합니다.
<bean id = "FirstCrontrigger"> <property name = "jobDetail"ref = "FirstTask" /> <속성 이름 = "cronexpression"value = "0/5 * * * *" /> < /bean>
JobDetail은 2 단계에서 구성된 작업을 지정하고 Cronexpression은 5 초마다 작업을 실행하도록 구성됩니다.
4. 석영 스케줄러의 SchedulerFactoryBean을 구성하십시오
메모리 RAMJOBSTORE 및 데이터베이스 방법의 두 가지 방법도 있습니다.
4.1 메모리 RAMJOBSTORE
작업 관련 정보는 메모리에 저장되며 각 노드는 자체적으로 저장하고 서로 격리하며 다음과 같이 구성됩니다.
<bean> <property name = "triggers"> <list> <Ref bean = "FirstCrontrigger"/> </list> </property> </bean>
4.2 데이터베이스 방법
작업의 관련 정보는 데이터베이스에 저장됩니다. 모든 노드는 데이터베이스를 공유합니다. 각 노드는 데이터베이스를 통해 통신하여 작업이 동시에 하나의 노드에서만 실행되도록합니다.
노드가 실패하면 작업을 다른 노드에 실행하기 위해 할당합니다. 특정 구성은 다음과 같습니다.
<bean id = "dataSource"Destroy-method = "close"> <property name = "driverclass"value = "com.mysql.jdbc.driver" /> <property name = "jdbcurl"value = "jdbc : mysql : // localhost : 3306 /quartz" /> <property name = "value ="root " /> <property name ="valess " </bean> <ean> <property name = "dataSource"ref = "dataSource"/> <property name = "configlocation"value = "classPath : Quartz.Properties"/> <property name = "triggers"> <list> <ref bean = "FirstCrontrigger"/> </property> </bean>
DataSource는 데이터 소스 및 데이터 테이블 관련 정보를 구성하는 데 사용됩니다. 공식 웹 사이트에서 GZ 패키지를 다운로드 할 수 있습니다. SQL 파일은 경로 아래에 있습니다 : Docs/DBtables는 주류 데이터베이스에 SQL 파일을 제공합니다.
configlocation에서 구성된 quartz.properties 파일은 org.quartz.jar의 org.quartz 패키지에 있습니다. 여기에는 org.quartz.jobstore.class와 같은 기본 데이터를 제공합니다.
org.quartz.jobstore.class : org.quartz.simpl.ramjobstore
여기에서 쿼츠를 복사하고 수정해야합니다. 특정 수정은 다음과 같습니다.
org.quartz.scheduler.instanceid : autoorg.quartz.jobstore.class : org.quartz.impl.jdbcjobstore.jobstoretxorg.quartz.jobstore.isclusted : trueorg.quartz.jobstore.clustercheckininterval : 1000
5. 관련 카테고리
공개 클래스 FirstTask는 QuartzJobbean {private FirstService FirstService; @override protected void executeInternal (jobExecutionContext Context) jobExecutionException {firstservice.service (); } public void setFirstService (FirstService FirstService) {this.FirstService = FirstService; }}FirstTask는 Quartzjobbean을 상속하고 ExecuteInternal 메소드를 구현하며 FirstService를 호출합니다
공개 클래스 FirstService는 직렬화 가능 {private static final long serialversionuid = 1L; public void service () {system.out.println (new simpledateformat ( "yyymmdd hh : mm : ss"). 형식 (new date ()) + "--- start firstService"); try {thread.sleep (2000); } catch (InterruptedException e) {e.printstacktrace (); } system.out.println (new SimpledateFormat ( "yyymmdd hh : mm : ss"). 형식 (new date ()) + "--- end firstService"); }}FirstService는 데이터베이스에 저장해야하므로 직렬화 인터페이스를 제공해야합니다.
공개 클래스 앱 {public static void main (string [] args) {acpractApplicationContext context = new ClassPathXmlApplicationContext ( "Quartz.xml"); }}메인 클래스는 석영 구성 파일을로드하는 데 사용됩니다.
분산 예약 테스트
1. 동시에 앱을 두 번 시작하고 로그를 관찰하십시오.
20180405 14:48:10 --- 시작 서비스를 시작하십시오
20180405 14:48:12 ---- 끝 서비스
20180405 14:48:15 --- 첫 번째 서비스를 시작하십시오
20180405 14:48:17 ---- 끝 서비스
그중 A1은 로그 출력이 있지만 A2는 그렇지 않습니다. A1이 중지되면 A2는 로그 출력이 있습니다.
2. 새로운 작업을 추가하고 새로운 작업을 각각 제작하십시오 : SecondSask 및 SecondService. 관련 구성 파일을 동시에 추가하십시오. 앱을 두 번 시작하고 로그를 관찰하십시오.
A1 로그는 다음과 같습니다.
20180405 15:03:15 --- 첫 번째 서비스를 시작하십시오
20180405 15:03:15 --- SecondService 시작
20180405 15:03:17 ---- 끝 서비스
20180405 15:03:17 --- 종료 초 서비스
20180405 15:03:20 --- 시작 서비스를 시작하십시오
20180405 15:03:22 ---- 끝 서비스
20180405 15:03:25 --- 첫 번째 서비스를 시작하십시오
20180405 15:03:27 ---- 끝 서비스
A2 로그는 다음과 같습니다.
20180405 15:03:20 --- SecondService를 시작하십시오
20180405 15:03:22 --- 종료 초 서비스
20180405 15:03:25 --- SecondService 시작
20180405 15:03:27 --- 종료 초 서비스
A1과 A2 모두 실행 작업이 있지만 동일한 작업이 동시에 한 노드에서만 실행되며 실행이 완료된 후 다른 노드에 할당 될 수 있습니다.
3. 예를 들어 간격 시간이 작업 실행 시간보다 작 으면 여기에서 수면으로 변경됩니다 (6000).
A1 로그는 다음과 같습니다.
20180405 15:14:40 --- 시작 서비스를 시작하십시오
20180405 15:14:45 --- 첫 번째 서비스를 시작하십시오
20180405 15:14:46 ----- 최초 서비스
20180405 15:14:50 --- 시작 서비스를 시작하십시오
20180405 15:14:50 --- SecondService를 시작하십시오
20180405 15:14:51 --- End FirstService
A2 로그는 다음과 같습니다.
20180405 15:14:40 --- SecondService 시작
20180405 15:14:45 --- SecondService 시작
20180405 15:14:46 --- 종료 초 서비스
20180405 15:14:51 --- 종료 초 서비스
간격은 5 초이고 작업 실행은 6 초가 걸립니다. 로그를 관찰하면 작업이 아직 끝나지 않았고 새로운 작업이 시작되었음을 알 수 있습니다. 이 상황은 응용 프로그램에서 논리적 문제를 일으킬 수 있으며, 실제로 작업이 연속을 지원할 수 있는지에 대한 문제입니다.
4. @DisallowConcurrentExecution 주석은 작업의 직렬화를 보장합니다
FirstStask 및 Secondstask에 각각 @DisallowConcurrentExecution 주석을 추가하면 로그 결과는 다음과 같습니다.
A1 로그는 다음과 같습니다.
20180405 15:32:45 --- 첫 번째 서비스를 시작하십시오
20180405 15:32:51 --- End FirstService
20180405 15:32:51 --- 첫 번째 서비스를 시작하십시오
20180405 15:32:51 --- SecondService 시작
20180405 15:32:57 ---- 끝 서비스
20180405 15:32:57 --- 종료 초 서비스
20180405 15:32:57 --- 첫 번째 서비스를 시작하십시오
20180405 15:32:57 --- SecondService 시작
A2 로그는 다음과 같습니다.
20180405 15:32:45 --- SecondService 시작
20180405 15:32:51 --- 종료 초 서비스
로그를 관찰하면 작업이 끝난 후에 만 새 작업을 시작하고 작업의 직렬화를 실현한다는 것을 알 수 있습니다.
요약
이 기사는 Spring+Quartz 분산 스케줄링에 대한 직관적 인 이해를 얻고 실제 사용을 통해 문제를 해결하는 것을 목표로합니다. 물론, 예약 방법, 데이터베이스가 매달려있을 때 어떻게 될지 등이있을 수 있으며 더 심층적 인 이해가 필요할 수 있습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.