programing

일정한 시간이 지난 후에 중단되는 경우 Spring Scheduled 실행 중지

bestprogram 2023. 7. 21. 21:45

일정한 시간이 지난 후에 중단되는 경우 Spring Scheduled 실행 중지

의 Spring Framework를 했습니다.Scheduledcroncron.을 합니다.하지만 때때로 제 일은 외부 리소스를 무한정 기다려서 시간 초과를 설정할 수 없습니다.사용할 수 없습니다.fixedDelay이전 프로세스가 무한 대기 모드로 전환되는 경우가 있으므로 5분마다 데이터를 새로 고쳐야 합니다.

저는 Spring의 Spring Framework에서 있었습니다.Scheduled잠시 후에 그 과정을 중단함fixed-time성공적으로 실행되거나 실행되지 않습니다.

.ThreadPoolExecutorkeepAliveTime을 내가넣에 .@Configuration수업입니다. 제가 예상했던 대로 잘 될 거라고 누가 말해줄 수 있나요?

@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
    int coreThreads = 8;
    int maxThreads = 20;
    final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            coreThreads, maxThreads, 120L, 
            TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()
    );
    threadPoolExecutor.allowCoreThreadTimeOut(true);

    return threadPoolExecutor;
}

이것이 예상대로 작동할지 확신할 수 없습니다.실제로 keepAlive는 IDLE 스레드용이며 리소스를 기다리는 스레드가 IDLE에 있는지 알 수 없습니다.또한 스레드 수가 코어 수보다 많을 때만 발생하므로 스레드 풀을 모니터링하지 않으면 언제 발생하는지 알 수 없습니다.

keepAliveTime - 스레드 수가 코어 수보다 많을 경우 유휴 스레드가 종료되기 전에 새 작업을 기다리는 최대 시간입니다.

다음과 같은 작업을 수행할 수 있습니다.

public class MyTask {

    private final long timeout;

    public MyTask(long timeout) {
        this.timeout = timeout;
    }

    @Scheduled(cron = "")
    public void cronTask() {
        Future<Object> result = doSomething();
        result.get(timeout, TimeUnit.MILLISECONDS);
    }

    @Async
    Future<Object> doSomething() {
        //what i should do
        //get ressources etc...
    }
}

추가하는 것을 잊지 마십시오.@EnableAsync

또한 이 기능을 사용하지 않고도 동일한 작업을 수행할 수 있습니다.@Async통화 가능 항목을 구현합니다.

편집: 시간이 초과될 때까지 대기하지만 작업을 실행하는 스레드는 중단되지 않습니다.시간 초과 시 Future.cancel을 호출해야 합니다.예외가 발생합니다.작업에서 isInterrupted()를 확인하여 처리를 중지합니다.api를 호출하는 경우 isInterrupted()가 선택되어 있는지 확인합니다.

코어 허용ThreadTimeOut시간 초과 설정은 작업 없이 일정 시간 후에 작업 스레드를 종료할 수 있도록 하는 데 도움이 되지 않습니다(javadocs 참조).

당신은 당신의 일이 외부 자원을 무한정 기다린다고 말합니다.기본적으로 시간 제한이 없는 소켓을 사용하기 때문일 것입니다.또한 jvm이 스레드를 무시하는 것도 염두에 두십시오.socket.connect/read에서 차단되었을 때 interrupt.

작업에 사용된 마녀 소켓 라이브러리(정확히 사용된 방법)를 확인하고 기본 시간 초과 설정을 변경합니다.

예: Spring 내부에서 널리 사용되는 RestTemplate가 있습니다(휴게 고객, Spring social, Spring security OAuth 등).또한 RestTemplate 인스턴스를 생성하기 위한 클라이언트 Http 요청 팩토리 구현이 있습니다.기본적으로 스프링은 JDK 소켓을 사용하는 SimpleClientHttpRequestFactory를 사용합니다.기본적으로 모든 제한 시간은 무한합니다.

따라서 정확하게 얼린 위치를 찾아 문서를 읽고 올바르게 구성하십시오.

추신: 시간이 충분하지 않고 "매우 운이 좋은" 경우 jvm 속성 sun.net .client.defaultConnectTimeout 및 sun.net .client.defaultReadTimeout을 일부 합리적인 값으로 설정하여 앱을 실행해 보십시오(자세한 내용은 문서 참조).

keepAliveTime이는 한동안 필요하지 않았던 작업자 스레드를 정리하기 위한 것입니다. 실행자에게 제출된 작업의 실행 시간에는 영향을 주지 않습니다.

시간이 걸리는 작업이 중단되면 새 스레드를 시작하고 시간 제한을 적용하여 조인할 수 있습니다. 이 스레드가 시간 내에 완료되지 않으면 스레드를 중단할 수 있습니다.

public class SomeService {

    @Scheduled(fixedRate = 5 * 60 * 1000)
    public void doSomething() throws InterruptedException {
        Thread taskThread = new TaskThread();
        taskThread.start();
        taskThread.join(120 * 000);
        if(taskThread.isAlive()) {
            // We timed out
            taskThread.interrupt();
        }
    }

    private class TaskThread extends Thread {

        public void run() {
            // Do the actual work here
        }
    }
}

언급URL : https://stackoverflow.com/questions/39917757/stop-spring-scheduled-execution-if-it-hangs-after-some-fixed-time