배경
프로젝트 개발 중에는 종종 정기적 인 작업을 수행해야합니다. 타이밍 작업을 통해 잘 달성하는 데 도움이 될 수 있습니다.
일반적으로 사용되는 몇 가지 시간이 정한 작업 프레임 워크를 비교해 봅시다.
위 표에서 볼 수 있듯이 스프링 스케줄 프레임 워크에는 완전한 기능이 있으며 간단하고 사용하기 쉽습니다. 봄 일정은 중소형 프로젝트에 대한 자격이 있습니다.
1. 스프링 부츠 통합 일정
1.1 Maven 의존성 패키지 추가
스프링 스케줄이 스프링 부트 스타터 기본 모듈에 포함되어 있으므로 추가 종속성이 필요하지 않습니다.
<pectionies> <pectinement> <groupId> org.springframework.boot </groupid> <artifactid> Spring-Boot-Starter </artifactid> </depectency> <groupIdency> <groupId> org.springframework.boot </groupid> <artifactid> spring-boot-starter-test> </artifactid> </종속성> </종속성>
1.2 클래스 시작, 시작 주석을 추가하십시오
스프링 부츠 항목 또는 구성 클래스에 @enablescheduling 주석을 추가하면 타이밍 작업이 가능할 수 있습니다.
@enablescheduling@springbootapplicationpublic class scheduleapplication {public static void main (string [] args) {springApplication.run (scheduleApplication.class, args);}}1.3. 시간이 정한 작업을 추가하십시오
스프링 일정의 세 가지 작업 스케줄러의 예를 제시 할 것입니다.
1.3.1 Cron 표현
Linux의 CRON 표현 시간 정의 규칙과 유사합니다. CRON 표현식은 아래 그림과 같이 시간 필드로 분리 된 6 개 또는 7 개의 공백으로 구성됩니다.
일반적인 표현 :
밤나무를 가져 가십시오 :
10 초마다 실행되는 Work () 메소드를 추가하십시오.
참고 : 메소드의 실행 시간이 작업 스케줄링 주파수를 초과하면 다음 사이클에서 스케줄러가 실행됩니다.
예를 들어 : Work () 메소드가 0 초에 실행되기 시작하고 방법이 12 초 동안 실행된다고 가정하면 다음에 Work () 메소드가 실행되면 20 초입니다.
@componentpublic class mytask {@scheduled (cron = "0/10 * * * * *") public void work () {// task execution logic}}1.3.2 고정 간격 작업
다음 작업 실행 시간은 메소드의 마지막 작업 실행 종료 시간부터 계산됩니다. 이 규칙을 사용하여 작업을 정기적으로 실행하십시오.
밤나무를 가져 가십시오 :
작업 () 메소드를 추가하고 10 초마다 실행하십시오.
예를 들어 : Work () 메소드가 0 초에 실행되기 시작하고 메소드가 12 초 동안 실행된다고 가정하면 다음에 Work () 메소드가 실행되면 22 초입니다.
@scheduled (fixedDelay = 1000*10) public void work () {// 작업 실행 로직}1.3.3 고정 주파수 작업
지정된 주파수에서 작업을 실행 하고이 규칙으로 일정을 정기적으로 실행하십시오.
밤나무를 가져 가십시오 :
10 초마다 실행되는 Work () 메소드를 추가하십시오.
참고 : 메소드의 실행 시간이 작업 스케줄링 주파수를 초과하면 현재 메소드가 실행 된 직후 스케줄러가 다음 작업을 실행합니다.
예를 들어 : Work () 메소드가 0 초에 실행되기 시작하고 메소드가 12 초 동안 실행된다고 가정하면 다음에 Work () 메소드가 실행되면 12 초입니다.
@scheduled (fixedrate = 1000*10) public void work () {// 작업 실행 로직}2. TaskScheduler 스레드 풀을 구성하십시오
실제 프로젝트에서 우리 시스템은 여러 타이밍 작업을 정의 할 수 있습니다. 그런 다음 여러 타이밍 작업을 독립적으로 수행 할 수 있습니다.
org.springframework.scheduling.config.scheduledtaskregistrar 소스 코드를 살펴보면 Spring은 기본적으로 단일 스레드 풀을 생성하는 것으로 나타났습니다. 이것은 멀티 태스킹에 치명적일 수 있습니다. 여러 작업이 동시에 실행되거나 동시에 실행 해야하는 경우 작업 스케줄러는 시간 드리프트를 경험하고 작업 실행 시간은 불확실합니다.
보호 된 void scheduletasks () {if (this.taskscheduler == null) {this.localexecutor = executors.newsingLethreadScheduledExecutor (); this.taskscheduler = new ConcurrentTaskScheduler (this.localexecutor);} // 생략 ...}2.1 사용자 정의 스레드 풀
SchedulingConfigurer 인터페이스를 구현하기 위해 구성 클래스를 추가했습니다. ConfigureTasks 메소드를 다시 작성하고 Taskregistrar를 통해 사용자 정의 스레드 풀을 설정하십시오.
@ConfigurationPublic Class ScheduleConfig는 SchedulingConfigurer {@overridepublic void configureTasks (scheduledTaskregistrar taskgistrar) {taskgreStar.setScheduler (taskexecutor ());}@bean (DestroyMethod = "hutdown")을 구현합니다. executors.newscheduledthreadpool (20);}}3. 실제 응용 분야의 문제
3.1 웹 응용 프로그램의 시작 및 종료 문제
우리는 스프링을 통해로드 또는 초기화 된 콩이 서비스가 중지되면 자동으로 내릴 (파괴)이라는 것을 알고 있습니다. 그러나 스레드는 JVM 레벨이므로 사용자가 웹 응용 프로그램에서 스레드를 시작하면이 스레드의 수명주기는 웹 응용 프로그램과 일치하지 않습니다. 즉, 웹 응용 프로그램이 중지 되더라도 스레드는 여전히 끝나지 않습니다 (죽음).
해결책:
1) 현재 객체는 스프링을 통해 초기화됩니다
스프링이 인스턴스를 제거 (파괴)하면 인스턴스의 파괴 방법이 호출됩니다. 일회용 비 인터페이스를 구현하여 구현. 파괴 방법에서 실을 적극적으로 닫습니다.
@ComponentPublic Class MyTask는 처분 가능 비안을 구현합니다. {@OverRidePublic void Destrove ()는 예외를 발생시킵니다 {// 스레드 또는 스레드를 닫습니다. 스레드 throod ThreadPoolTaskScheduler scheduler = (ThreadPooltaskScheduler) ApplicationContext.getBean ( "Scheduler"); scheduleler.shutdown ();} //} //}}.2) 현재 객체는 스프링을 통해 초기화 (관리)되지 않습니다.
그런 다음 서블릿 서비스가 중지 될 때 스레드를 적극적으로 닫기 위해 서블릿 컨텍스트 리스너를 추가 할 수 있습니다.
공개 클래스 MyTaskListenter는 ServletContextListener를 구현합니다.
3.2 분산 배치 문제
실제 프로젝트에서 우리 시스템은 일반적으로 클러스터, 분산 또는 재해 복구에 배치됩니다. 그런 다음 타이밍 작업에 동시성 문제가 발생할 수 있습니다. 즉, 동일한 작업이 여러 서버에서 동시에 실행됩니다.
솔루션 (분산 잠금) :
1) 데이터베이스 테이블을 통해 잠그십시오
2) 캐시 미들웨어
3) Zookeeper를 통해 구현
요약 :
스프링 일정은 간단하고 빠르며 효율적이며 안정적인 타이밍 작업 프레임 워크를 제공합니다. 그러나 스레드와 분산 배포 문제의 수명주기를 고려해야합니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.