簡體   English   中英

Spring 任務異步和延遲

[英]Spring Task Async and Delayed

我需要做一件我不知道的事情,這是最好的做法。

在我向特定服務發送一個請求后,這個請求返回 OK 並將我的請求排入隊列。 我有一個回調服務,用於通知何時結束。

問題是整個過程可能需要很長時間,而且沒有通知任何內容,之后我需要考慮超時。

該應用程序是 SpringBoot APP,我正在考慮在具有睡眠時間的服務方法上使用 @EnableAsync 和 @Async 注釋。

@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("TIMCLL-");
        executor.initialize();
        return executor;

    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        // TODO Auto-generated method stub
        return null;
    }

}

. . .

@Async
public void verifyStatusTimPayment() throws InterruptedException {

    Thread.sleep(5000);
    logger.info( "Executed after 5s " +  new SimpleDateFormat("dd/MM/yyyy hh:mm:ss").format(new Date())); 

}

驗證需要在請求后 15 分鍾完成,並且每個請求只能進行一次。

我怎么能不做一個 Thread.sleep 呢???????

可以使用ScheduledExecutorService來安排任務

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
...
scheduler.schedule(() -> {yourtaskhere}, 15, TimeUnit.MINUTES);

但這不是你想要的。 如果服務器在任務調度和執行之間死機怎么辦? 你會失去你的任務。 如果您將消息保存在隊列中並稍后檢索它,或者使用任何使用持久性的調度程序(a la Quartz)會更好

我想我們可以在最近的春天使用@Scheduled。 它將每 15 分鍾運行一次,就像方法注釋如下

@Scheduled(cron = "0 0/15 * * * *")
public void verifyStatusTimPayment() throws InterruptedException {
    logger.info( "Executed after 5s " +  new SimpleDateFormat("dd/MM/yyyy hh:mm:ss").format(new Date())); 

}

我知道我遲到了,但可能會幫助正在經歷線程的人

您可以將 @EnableScheduling 注釋添加到您的配置中:

@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfiguration implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("TIMCLL-");
        executor.initialize();
        return executor;

    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        // TODO Auto-generated method stub
        return null;
    }

}

如果您想安排一次並延遲,您可以調用 taskScheduler :

@Autowired 
private TaskScheduler taskScheduler;

並執行任務:

taskScheduler.schedule(
    () -> {//your task}, 
    //Your Delay task
);

您可以使用 Redis 支持的延遲調度程序,這將保證您不會丟失任務。 這可以很容易地使用Rqueue來完成。

在 Rqueue 中,您可以將 15 分鍾后運行的任務排入隊列

public class Verification {
    private String id;
}

@Component
class VerificationListener {
  @RqueueListener(
  value = "verification-queue")
  public void onMessage(Verification verification) {
    // do verification 
  }
}


@Service
class DelayedTaskService {
    @Autowired private RqueueMessageSender rqueueMessageSender
    public void enqeueVerification(Verification verification) {
         rqueueMessageSender.enqueuIn("verification-queue", verification, Duration.ofMinutes(15);
    }
}

PS 我是 Rqueue 庫的開發人員。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM