스프링 스케줄링 작업 - 한 번만 실행
Spring service method는 정확히 지정된 시간에 한 번만 스케줄이 가능합니까?예를 들어, 현재 시간은 오후 2시이지만 액션 버튼을 누르면 오후 8시에 서비스가 시작되기를 원합니다.저는 @Scheduled 주석에 익숙하며 주기적으로 실행되지 않도록 cron 식을 작성하는 방법을 잘 모르겠습니다.이것@Scheduled(cron = "0 0 20 * * ?")
매일 오후 8시에 화재가 발생합니다.
좋은 의견이라도 있나?
죽은 자의 해결책:
@Scheduled(initialDelay = 1000 * 30, fixedDelay=Long.MAX_VALUE)
다시 불이 나기 전에 당신은 죽을 겁니다.
Spring's Task Scheduler의 구현 중 하나를 사용할 수 있습니다.아래에 너무 많은 구성이 필요하지 않은 예제(싱글 스레드의 예약된 실행자를 래핑하는 동시 작업 스케줄러)를 제공했습니다)를 제공했습니다.
가장 간단한 방법은 실행 가능한 예약과 날짜만 사용하는 예약입니다.그러면 지정된 시간 후에 작업이 한 번 실행됩니다.다른 모든 메서드는 반복적으로 실행되는 태스크를 예약할 수 있습니다.
간단한 작업 예제:
private TaskScheduler scheduler;
Runnable exampleRunnable = new Runnable(){
@Override
public void run() {
System.out.println("Works");
}
};
@Async
public void executeTaskT() {
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
scheduler = new ConcurrentTaskScheduler(localExecutor);
scheduler.schedule(exampleRunnable,
new Date(1432152000000L));//today at 8 pm UTC - replace it with any timestamp in miliseconds to text
}
...
executeTaskT() //call it somewhere after the spring application has been configured
참고:
@Scheduled 및 @Async 주석에 대한 지원을 활성화하려면 @Configuration 클래스 중 하나에 @EnableScheduling 및 @EnableAsync를 추가합니다.
업데이트 - 스케줄링된 작업 취소
TaskScheduler의 Scheduled Future 메서드는 취소할 수 있는 지연된 결과가 포함된 작업인 Scheduled Future를 반환합니다.
따라서 취소하려면 예약된 작업(즉, 예약된 미래 반환 개체 유지)을 처리해야 합니다.
작업을 취소하기 위해 위의 코드가 변경되었습니다.
- executeTaskT 메서드 외부의 ScheduledFuture를 선언합니다.
private ScheduledFuture scheduledFuture;
- 다음과 같이 반환 개체를 유지하도록 예약하도록 통화를 수정합니다.
scheduledFuture = scheduler.schedule(exampleRunnable,
new Date(1432152000000L));
- 코드의 어딘가에 있는 예약된 Future 개체에 대해 취소 호출
boolean mayInterruptIfRunning = true;
scheduledFuture.cancel(mayInterruptIfRunning);
정기 트리거를 다음과 같이 연장할 수 있습니다. 이 트리거는 마지막 완료를 확인합니다.시간: 작업이 이전에 실행된 적이 없으면 null입니다.지정된 시간에 한 번만 태스크를 실행하려는 경우 이 버전을 사용해 볼 수 있습니다.
class RunOnceTrigger extends PeriodicTrigger {
public RunOnceTrigger(long period) {
super(period);
setInitialDelay(period);
}
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
if(triggerContext.lastCompletionTime() == null) { // hasn't executed yet
return super.nextExecutionTime(triggerContext);
}
return null;
}
}
생성하지 않으려면ScheduledExecutorService
그리고.ConcurrentTaskScheduler
모든 메서드 호출에서 초기화하는 것이 편리합니다.TaskScheduler
서비스 생성 시, 예:
private final TaskScheduler taskScheduler =
new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(10));
@Async
작업을 예약하고 메서드를 종료하기 때문에 의미가 없습니다.
Spring 6.0.10/Spring Boot 3.0.8 이후의 ThreadPool Task Scheduler 구현은 모든 지연을 나노초로 변환합니다.불행하게도 주석은@Scheduled
를 사용합니다.TimeUnit
중, 실행 중, 실행 중
@Scheduled(initialDelay = ..., fixedDelay=Long.MAX_VALUE)
을 "으"로 해제합니다.java.lang.ArithmeticException: long overflow
변환하기 때문입니다.Long.MAX_VALUE
밀리초는 오래 걸리지 않을 것입니다.
쉬운 해결 방법은 나노초를 선택하여 고정 지연을 제한하는 것입니다.
@Scheduled(initialDelay = 1000 * 30, fixedDelay=Long.MAX_VALUE, timeUnit = TimeUnit.NANOSECONDS )
이렇게 하면 지연 시간이 3억 년에서 300년 미만으로 줄어들지만, 가장 혼란스러운 배치 일정에도 충분할 것입니다.
이미 진행 중인 수정 사항이 있습니다. https://github.com/spring-projects/spring-framework/commit/599ac58baa049d0075edf802cf056ffa7112fc87
질문의 제목은 원샷 작업 러너가 필요하다는 것을 의미합니다.다음은 지연 후 한 번 실행되는 작업 클래스입니다(또는 OP 요청에 따라 에폭으로 대체).또한 application.properties/yaml 또는 프로필에서 활성화/비활성화할 수 있습니다.
@Slf4j
@Component
@ConditionalOnProperty({ "app.scheduler.onceRunner" })
public class RunOnceTask
{
public static final long INITIAL_DELAY_SECS = 5L; // As you wish
@Autowired
@Qualifier("mainTaskScheduler") // You could set a custom TPTS to set threads, name, etc.
private ThreadPoolTaskScheduler poolTaskScheduler;
@PostConstruct
public void run()
{
poolTaskScheduler.scheduleWithFixedDelay( () -> {
log.info( "Once-runner ran once" );
}, new Date( System.currentTimeMillis() + (INITIAL_DELAY_SECS * 1000) ), Long.MAX_VALUE ); // Run once
}
}
언급URL : https://stackoverflow.com/questions/30347233/spring-scheduling-task-run-only-once
'programing' 카테고리의 다른 글
Intel 프로세서와 AMD 프로세서의 어셈블리어가 동일합니까? (0) | 2023.08.25 |
---|---|
Powershell의 텍스트 파일에 내용 삽입 (0) | 2023.08.25 |
Powershell에서 -Verbose 인수가 주어졌는지 확인할 수 있습니까? (0) | 2023.08.25 |
표면도:매트플롯립 (0) | 2023.08.25 |
프로그래밍 방식으로 "Windows 바탕 화면을 이 모니터로 확장" (0) | 2023.08.25 |