런타임에 Spring의 @Scheduled fixed delay를 변경하는 방법은 무엇입니까?
일정한 간격으로 배치 작업을 실행해야 하며 런타임에 이 배치 작업의 시간을 변경할 수 있습니다.이것 때문에 우연히 발견했습니다.@Scheduled
주석이 Spring 프레임워크에서 제공되었습니다.하지만 런타임에 fixedDelay 값을 어떻게 변경해야 할지 모르겠습니다.저는 검색을 좀 해봤지만 유용한 것을 찾지 못했습니다.
스프링 부트에서는 응용 프로그램 속성을 직접 사용할 수 있습니다!
예:
@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds}000")
private void process() {
// your impl here
}
속성이 정의되지 않은 경우(예: 기본값이 "60"(초)인 경우)에도 기본값을 지정할 수 있습니다.
@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds:60}000")
제가 발견한 다른 것들:
- 메서드는 유효하지 않아야 합니다.
- 메서드에 매개 변수가 없어야 합니다.
- 방법은 아마도
private
사용할 수 있다는 것을 알게 되었습니다.private
편리한 가시성 및 다음과 같은 방식으로 사용:
@Service
public class MyService {
public void process() {
// do something
}
@Scheduled(fixedDelayString = "${my.poll.fixed.delay.seconds}000")
private void autoProcess() {
process();
}
}
존재private
예약된 메서드는 서비스에 대해 로컬일 수 있으며 서비스의 API에 포함되지 않을 수 있습니다.
또한, 이 접근 방식은 다음을 가능하게 합니다.process()
값을 반환하는 방법, 즉@Scheduled
방법이 아닐 수도 있습니다.예를 들어, 당신의process()
방법은 다음과 같습니다.
public ProcessResult process() {
// do something and collect information about what was done
return processResult;
}
처리 중 발생한 작업에 대한 정보를 제공합니다.
를 사용할 수 있습니다.Trigger
다음 실행 시간을 동적으로 설정합니다.
자세한 내용은 프로그래밍 방식으로 Spring 작업 예약에 대한 내 답변을 참조하십시오.
인터페이스를 만듭니다.
public abstract class DynamicSchedule{
/**
* Delays scheduler
* @param milliseconds - the time to delay scheduler.
*/
abstract void delay(Long milliseconds);
/**
* Decreases delay period
* @param milliseconds - the time to decrease delay period.
*/
abstract void decreaseDelayInterval(Long milliseconds);
/**
* Increases delay period
* @param milliseconds - the time to increase dela period
*/
abstract void increaseDelayInterval(Long milliseconds);
}
다음으로 스프링 컨텍스트 프로젝트에서 org.springframework.scheduling에 있는 트리거 인터페이스를 구현하겠습니다.
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import java.util.Date;
import java.util.concurrent.ScheduledFuture;
public class CustomDynamicSchedule extends DynamicSchedule implements Trigger {
private TaskScheduler taskScheduler;
private ScheduledFuture<?> schedulerFuture;
/**
* milliseconds
*/
private long delayInterval;
public CustomDynamicSchedule(TaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
}
@Override
public void increaseDelayInterval(Long delay) {
if (schedulerFuture != null) {
schedulerFuture.cancel(true);
}
this.delayInterval += delay;
schedulerFuture = taskScheduler.schedule(() -> { }, this);
}
@Override
public void decreaseDelayInterval(Long delay) {
if (schedulerFuture != null) {
schedulerFuture.cancel(true);
}
this.delayInterval -= delay;
schedulerFuture = taskScheduler.schedule(() -> { }, this);
}
@Override
public void delay(Long delay) {
if (schedulerFuture != null) {
schedulerFuture.cancel(true);
}
this.delayInterval = delay;
schedulerFuture = taskScheduler.schedule(() -> { }, this);
}
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
Date lastTime = triggerContext.lastActualExecutionTime();
return (lastTime == null) ? new Date() : new Date(lastTime.getTime() + delayInterval);
}
}
이제 구성:
@Configuration
public class DynamicSchedulerConfig {
@Bean
public CustomDynamicSchedule getDynamicScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.initialize();
return new CustomDynamicSchedule(threadPoolTaskScheduler);
}
}
및 용도:
@EnableScheduling
@Component
public class TestSchedulerComponent {
@Autowired
private CustomDynamicSchedule dynamicSchedule;
@Scheduled(fixedDelay = 5000)
public void testMethod() {
dynamicSchedule.delay(1000l);
dynamicSchedule.increaseDelayInterval(9000l);
dynamicSchedule.decreaseDelayInterval(5000l);
}
}
이를 위해 스프링 표현 언어(SpEL)를 사용할 수도 있습니다.
@Scheduled(fixedDelayString = "#{@applicationPropertyService.getApplicationProperty()}")
public void getSchedule(){
System.out.println("in scheduled job");
}
@Service
public class ApplicationPropertyService {
public String getApplicationProperty(){
//get your value here
return "5000";
}
}
AFAIK Spring API는 트리거를 변경하는 데 필요한 내부에 액세스할 수 없도록 합니다.대신 수동으로 콩을 구성할 수 있습니다.
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="jobDetail" />
<property name="startDelay" value="10000" />
<property name="repeatInterval" value="50000" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
SchedulerFactoryBean에 설명된 대로:
런타임에 작업을 동적으로 등록하려면 이 SchedulerFactoryBean에 대한 참조를 사용하여 Quartz Scheduler(쿼츠 스케줄러)에 직접 액세스합니다.
org.quartz.Scheduler
이렇게 하면 새 작업과 트리거를 생성하고 전체 스케줄러를 제어 및 모니터링할 수 있습니다.
저도 같은 문제를 다루었습니다.우리는 런타임에 cron 표현식을 변경하고 서비스를 다시 예약해야 합니다.그래서 다음과 같은 것이 있어야 합니다.
- 재컴파일 안 함
- 재배치 없음
- 다시 시작 안 함
신청서의.저는 인기 있는 솔루션을 모두 검사했지만 그 중 2개만 모든 요구 사항을 충족합니다.
- 제안된 대로 SchedulingConfigurer 구현
- 여기에 설명된 대로 사용자 지정 솔루션 사용
SchedulingConfigurer 접근 방식의 단점은 풀 기반이라는 것입니다. 즉, 서비스의 비즈니스 로직이 실행될 때마다 스케줄링 구성이 풀됩니다.일반적으로 나쁜 것은 아니지만 구성이 거의 변경되지 않고 실행 간격이 짧으면 불필요한 요청이 많이 발생합니다.
사용자 지정 솔루션의 단점은 코딩이 조금 더 필요하지만 푸시 기반이며 구성 변경에 대응하여 불필요한 요청/호출이 수행되지 않는다는 것입니다.
언급URL : https://stackoverflow.com/questions/15250928/how-to-change-springs-scheduled-fixeddelay-at-runtime
'sourcecode' 카테고리의 다른 글
ENTRYPOINT 배열에서 도커 환경 변수를 사용하려면 어떻게 해야 합니까? (0) | 2023.08.26 |
---|---|
JQuery Ajax 요청:사용자-에이전트 변경 (0) | 2023.08.21 |
텍스트 파일에서 변수를 검색하는 PowerShell (0) | 2023.08.21 |
Java 프로그램에서 MariaDB에 액세스하려고 하면 암호가 올바르는데도 'access denied' 예외가 발생하는 이유는 무엇입니까? (0) | 2023.08.21 |
공유 EntityManager에서 트랜잭션을 생성할 수 없음 - Spring 트랜잭션 또는 EJB CMT 사용 (0) | 2023.08.21 |