gpt4 book ai didi

java - Spring 启动 : gracefully shutdown by controlling termination order involving MongoClient

转载 作者:行者123 更新时间:2023-12-05 00:57:08 24 4
gpt4 key购买 nike

我有一个 Spring Boot 应用程序,它使用 AsyncTaskExecutor 生成许多线程(数量是预定义的)

线程执行一个无限循环,从一些队列和进程对象中读取,所以我并没有真正的拒绝策略机制(比如接受 tasks 的 ThreadPool)

问题在于,当应用程序关闭时,线程可能(并且可能)忙于处理一个项目,其中包括使用 MongoTemplate 对 Mongo 进行的操作。

因此,当应用程序关闭时,MongoClient 会自动close(),然后我会从 Mongo 收到一些错误,例如:

java.lang.IllegalStateException: The pool is closed
at com.mongodb.internal.connection.ConcurrentPool.get(ConcurrentPool.java:137)
at com.mongodb.internal.connection.DefaultConnectionPool.getPooledConnection(DefaultConnectionPool.java:262)
at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:103)
at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:92)
at com.mongodb.internal.connection.DefaultServer.getConnection(DefaultServer.java:85)

如何优雅地关闭应用程序?例如在尚未关闭 MongoClient 的同时中断线程?

代码:

创建 bean :

@Bean
AsyncTaskExecutor getTaskExecutor() {
SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
return executor;
}

简单地执行:

executor.execute(runnable);

最佳答案

不要使用 SimpleAsyncTaskExecutor - SimpleAsyncTaskExecutor 会为每个请求创建一个新线程,而是使用 ThreadPoolTask​​Executor 并配置下面提到的两个属性。

/**
* Set whether to wait for scheduled tasks to complete on shutdown,
* not interrupting running tasks and executing all tasks in the queue.
* <p>Default is "false", shutting down immediately through interrupting
* ongoing tasks and clearing the queue. Switch this flag to "true" if you
* prefer fully completed tasks at the expense of a longer shutdown phase.
* <p>Note that Spring's container shutdown continues while ongoing tasks
* are being completed. If you want this executor to block and wait for the
* termination of tasks before the rest of the container continues to shut
* down - e.g. in order to keep up other resources that your tasks may need -,
* set the {@link #setAwaitTerminationSeconds "awaitTerminationSeconds"}
* property instead of or in addition to this property.
* @see java.util.concurrent.ExecutorService#shutdown()
* @see java.util.concurrent.ExecutorService#shutdownNow()
*/
public void setWaitForTasksToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) {
this.waitForTasksToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
}

/**
* Set the maximum number of seconds that this executor is supposed to block
* on shutdown in order to wait for remaining tasks to complete their execution
* before the rest of the container continues to shut down. This is particularly
* useful if your remaining tasks are likely to need access to other resources
* that are also managed by the container.
* <p>By default, this executor won't wait for the termination of tasks at all.
* It will either shut down immediately, interrupting ongoing tasks and clearing
* the remaining task queue - or, if the
* {@link #setWaitForTasksToCompleteOnShutdown "waitForTasksToCompleteOnShutdown"}
* flag has been set to {@code true}, it will continue to fully execute all
* ongoing tasks as well as all remaining tasks in the queue, in parallel to
* the rest of the container shutting down.
* <p>In either case, if you specify an await-termination period using this property,
* this executor will wait for the given time (max) for the termination of tasks.
* As a rule of thumb, specify a significantly higher timeout here if you set
* "waitForTasksToCompleteOnShutdown" to {@code true} at the same time,
* since all remaining tasks in the queue will still get executed - in contrast
* to the default shutdown behavior where it's just about waiting for currently
* executing tasks that aren't reacting to thread interruption.
* @see java.util.concurrent.ExecutorService#shutdown()
* @see java.util.concurrent.ExecutorService#awaitTermination
*/
public void setAwaitTerminationSeconds(int awaitTerminationSeconds) {
this.awaitTerminationSeconds = awaitTerminationSeconds;
}

相关部分

Set the maximum number of seconds that this executor is supposed to block on shutdown in order to wait for remaining tasks to complete their execution before the rest of the container continues to shut down. This is particularly useful if your remaining tasks are likely to need access to other resources that are also managed by the container.

您可以使用spring自动配置来控制任务执行属性(首选)或以编程方式使用@Bean注解

2.1.0 中的 Spring boot 为任务执行器提供自动配置,并用于 @EnableAsync 和 Spring MVC 异步支持。

应用程序不需要任务执行器 bean/webMvcConfigurer 配置。所以删除你有的,应该是好的。

您可以使用带有 spring.task.execution.* 的应用程序属性/yml 文件进行调整。

spring.task.execution.shutdown.await-termination=true
spring.task.execution.shutdown.await-termination-period=60

可以找到完整列表 here

更多详情 herehere

@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(5);
taskExecutor.waitForTasksToCompleteOnShutdown(true);
taskExecutor.setAwaitTerminationSeconds(60);
return taskExecutor;
}

关于java - Spring 启动 : gracefully shutdown by controlling termination order involving MongoClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61187699/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com