1、用springboot里的org.quartz.Scheduler组件时,一开始使用不当,创建了一千来个schedule,里边有一段逻辑,是会连接一些mysql表进行查询的逻辑。 前些天每隔一段时间就会报连接池拿不到连接了,推测是因为连接被耗尽。 2、后来改了一下代码,只创建一个schedule,但是在里边循环一千来次这个逻辑,去读mysql表。 3、如果再进行改造,对这一千次循环拆分成多线程来跑呢? 我的疑问是,这3种情况,到底对mysql连接池产生的并发访问压力是什么样的?
我是在springboot里用的hikari组件对mybatis进行的管理,所以连接的释放啊、锁啊之类的都没关注,都是让框架自己管理了,然后多线程也是用的hutool里的threadutil.execute();也没有去定多少个线程数什么的。
在使用Spring Boot和Quartz调度任务时,你遇到的问题主要与MySQL连接池的管理和并发访问有关。我们可以通过分析这三种情况,来了解它们对MySQL连接池产生的并发访问压力以及可能的改进方法。
在这种情况下,1000个Scheduler独立运行,它们可能同时访问MySQL数据库。如果每个Scheduler都在同一时间进行数据库查询,这会导致非常高的并发数据库连接请求,可能导致连接池耗尽。
并发访问压力: - 每个Scheduler都可能在同一时间进行数据库操作。 - 如果连接池大小不够,很多Scheduler会因为无法获取连接而等待,导致连接池耗尽。 - 这种情况对数据库服务器的压力非常大,可能导致性能问题。
在这种情况下,只有一个Scheduler在运行,但它循环1000次进行数据库操作。虽然Scheduler的数量减少了,但循环中的每次操作还是会进行数据库访问。
并发访问压力: - 由于是单线程循环操作,数据库连接的并发请求数会比情况1少。 - 连接池的压力会减小,但由于所有操作都在单线程中进行,总体运行时间可能会变长。 - 这种方式不会立即耗尽连接池,但性能依然可能受到影响,因为一次性操作的次数太多。
将1000次循环操作拆分成多线程执行,这样可以利用多线程的并发处理能力,加快任务执行速度。但是,这样也会增加并发数据库访问请求。
并发访问压力: - 并发线程数将直接影响到数据库的并发请求数。 - 如果线程数过多,可能会导致连接池耗尽,类似于情况1。 - 需要合理设置线程数和连接池大小,来平衡性能和资源利用。
maximumPoolSize
yaml spring.datasource.hikari.maximum-pool-size: 50
ThreadPoolExecutor
```java // 创建固定大小的线程池 int corePoolSize = 10; // 根据实际情况设置 ExecutorService executorService = Executors.newFixedThreadPool(corePoolSize);
for (int i = 0; i < 1000; i++) { executorService.execute(() -> { // 你的逻辑 }); }
executorService.shutdown(); ```
批量处理: 尽量使用批量查询来减少数据库连接的次数。例如,如果每次查询的数据量不是很大,可以一次性查询多个记录,然后在内存中进行处理。
连接池监控: 监控连接池的使用情况,调整连接池参数和并发策略,确保连接池不会被耗尽。
异步调度: 使用异步调度来分散任务执行时间,避免瞬时高并发。例如,可以在调度任务中引入一定的延迟或调度策略,使任务执行更加均匀。
import cn.hutool.core.thread.ThreadUtil; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class SchedulerTask { public static void main(String[] args) { int corePoolSize = 10; // 设置合理的线程池大小 ExecutorService executorService = Executors.newFixedThreadPool(corePoolSize); for (int i = 0; i < 1000; i++) { executorService.execute(() -> { // 你的逻辑,例如数据库查询 queryDatabase(); }); } executorService.shutdown(); } private static void queryDatabase() { // 数据库查询逻辑 } }
通过以上方法,可以更好地控制并发访问对MySQL连接池的压力,确保应用程序的稳定性和性能。