如果方法A在Spring Boot中执行的时间超过X秒,则退回到方法B

时间:2018-12-20 15:59:08

标签: java spring-boot hystrix

我有一个Spring Boot应用程序,我有一个@Service,它很重,可以执行0.5到5秒。如果执行时间超过1秒并回退为回退方法,我希望它停止执行。

/// entry point
public String longLatingMethod(Payload payload) {
    /// long lasting operation that can take up to 5 seconds
    return value; 
}

// I want this method to be executed if `longLatingMethod` takes more than 1 second to execute.
public String fallbackMethod(Payload payload) {
    return defaultValue;
}

现在我已经使用Hystrix框架实现了该功能,但是由于Hystrix已停产,因此我想知道还有什么其他库?

3 个答案:

答案 0 :(得分:0)

您必须在某种线程中运行任务,以便您可以继续执行并等待(一定毫秒数)以使该过程完成。如果未在指定时间内完成,请中断主要任务并运行备份任务。请注意,您的主要任务将必须检查它是否被中断,阻塞操作通常已经对此进行了检查,并且在中断时将停止阻塞。

public static void main(String[] args){
    Thread t = new Thread(() -> {
        // your long running task here...
        System.out.println("running primary task");

        // simulate it taking too long...
        // will need to check if it is interrupted if you want to terminate it sooner
        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            System.out.println("primary task interrupted");
        }
    });
    t.start();

    // one second threshold
    try { t.join(1000); } catch (Exception e) {}

    if (t.isAlive()) {
        // if the primary task is still running interrupt it
        t.interrupt();

        // run your backup task
        System.out.println("running backup task");
        // ...
        System.out.println("backup task completed");
    } else {
        System.out.println("primary task completed");
    }
}

输出:

running primary task
running backup task
primary task interrupted
backup task completed

答案 1 :(得分:0)

您可以使用Future尤其是方法V get(long timeout, TimeUnit unit)

  

在必要的情况下最多等待给定时间以完成计算,然后检索其结果(如果有)。

并按以下方式使用它:

<?php 
if(have_posts()){
    while(have_posts()){
        the_post();
        //echo wp_count_posts();
    ?>
    <h1><?php echo the_title(); ?></h1>
    <h3><?php echo the_content();?></h3>
    <hr>
    <?php

    }
}
?>

请注意,如果您不定期修改某个方法是否完成检查,就无法停止该方法的执行,但是通常无法执行,例如,您是否要求对数据库进行查询,查询需要5秒钟,您无法在5秒钟之前检查。

答案 2 :(得分:-1)

不确定是不是最佳解决方案,请检查以下问题:Java: set timeout on a certain block of code?

然后在超时捕获块中添加回退

final Runnable stuffToDo = new Thread() {
  @Override 
  public void run() { 
    /* Do stuff here. */ 
  }
};

final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future future = executor.submit(stuffToDo);
executor.shutdown(); // This does not cancel the already-scheduled task.

try { 
  future.get(1, TimeUnit.Seconds); 
}
catch (InterruptedException ie) { 
  /* Handle the interruption. Or ignore it. */ 
}
catch (ExecutionException ee) { 
  /* Handle the error. Or ignore it. */ 
}
catch (TimeoutException te) { 
    return fallbackMethod(payload);
}