简体   繁体   English

Kotlin 如果失败则重试计划的 cron 任务

[英]Kotlin retry scheduled cron task if failed

I have a Kotlin scheduling config file below.我在下面有一个 Kotlin 调度配置文件。 It has an important task scheduled to run at 11am each Monday.它有一项重要任务计划在每周一上午 11 点运行。

What do I need to do for building resiliency or retry attempts in case the service is down at 11am?如果服务在上午 11 点停机,我需要做什么来建立弹性或重试?

Can these Spring Boot and Kotlin @Scheduled jobs be configured for enterprise level resiliency or do I need to look to use something like Kube.netes CronJobs to achieve this?这些 Spring Boot 和 Kotlin @Scheduled作业是否可以配置为企业级弹性,或者我是否需要使用 Kube.netes CronJobs 之类的东西来实现这一点?

@Component
class CronConfig {

    private val logger = LoggerFactory.getLogger(CronConfig::class.java)

    // Run Monday morning @ 11am
    @Scheduled(cron = "0 0 11 * * MON")
    fun doSomething(){
        logger.info("Doing something")
    }
}

It's good that you're thinking about what might go wrong.很好,您正在考虑 go 可能出错的地方。 (Too often we developers assume everything will go right, and don't consider and handle all the ways our code could fail!) (我们开发人员经常假设一切都会 go 正确,并且不考虑和处理我们的代码可能失败的所有方式!)

Unfortunately, I don't think there's a standard practice for this;不幸的是,我认为这没有标准的做法; the right approach probably depends on your exact situation.正确的方法可能取决于您的具体情况。

Perhaps the simplest approach is just to ensure that your function cannot fail , by doing error-handling, and if needed waiting and retrying, within it.也许最简单的方法就是确保您的 function 不会失败,方法是进行错误处理,并在需要时等待并重试。 You could split the actual processing out to a separate method if that makes it more readable, eg:如果这样可以使其更具可读性,您可以将实际处理拆分为一个单独的方法,例如:

@Scheduled(cron = "0 0 11 * * MON")
fun doSomethingDriver() {
    while (true) { // Keep trying until successful…
        try {
            doSomething()
            return // It worked!
        } catch (x: Exception) {
            logger.error("Can't doSomething: {}.  Will retry…", x.message)
            TimeUnit.SECONDS.sleep(10L)
        }
    }
}

fun doSomething() {
    logger.info("Doing something")
    // …
}

That's pretty straightforward.这很简单。 One disadvantage is that it keeps the thread waiting between retries;一个缺点是它使线程在重试之间保持等待; since Spring uses a single-threaded scheduler by default (see these questions ), that means it could delay any other scheduled jobs.由于 Spring 默认使用单线程调度程序(请参阅这些问题),这意味着它可能会延迟任何其他计划的作业。

Alternatively, if your scheduled function doesn't keep retrying, then you'll need some other way to trigger a retry.或者,如果您预定的 function没有继续重试,那么您将需要一些其他方式来触发重试。

You could 'poll': store the time of the last successful run, change the scheduled function to run much more frequently, and have it check whether another run is needed (ie whether there's been no successful run since the last 11am Monday).您可以“轮询”:存储上次成功运行的时间,将计划的 function 更改为更频繁地运行,并让它检查是否需要另一次运行(即自上次星期一上午 11 点以来是否没有成功运行)。 This will be more complex — especially as it needs to maintain state and do date/time processing.这将更加复杂——尤其是因为它需要维护 state 并进行日期/时间处理。 (You shouldn't need to worry about concurrency, though, unless you've made the function @Async or set up your own scheduling config.) It's also a little less efficient, due to all the extra scheduled wake-ups. (不过,您不必担心并发性,除非您已经创建了 function @Async或设置了您自己的调度配置。)由于所有额外的预定唤醒,它的效率也有点低。

Or you could trap errors (like the code above) but instead of waiting and retrying, manually schedule a retry for a future time, eg using your own TaskExecutor .或者您可以捕获错误(如上面的代码)但不是等待和重试,而是手动安排将来重试,例如使用您自己的TaskExecutor This would also be more complex.这也会更复杂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM