1、用springboot里的org.quartz.Scheduler组件时,一开始使用不当,创建了一千来个schedule,里边有一段逻辑,是会连接一些mysql表进行查询的逻辑。
前些天每隔一段时间就会报连接池拿不到连接了,推测是因为连接被耗尽。
2、后来改了一下代码,只创建一个schedule,但是在里边循环一千来次这个逻辑,去读mysql表。
3、如果再进行改造,对这一千次循环拆分成多线程来跑呢?
我的疑问是,这3种情况,到底对mysql连接池产生的并发访问压力是什么样的?
感谢各位的回答。
有点补充:我是在springboot里用的hikari组件对mybatis进行的管理,所以连接的释放啊、锁啊之类的都没关注,都是让框架自己管理了,然后多线程也是用的hutool里的threadutil.execute();也没有去定多少个线程数什么的。
在这种情况下,你遇到的问题可能与连接池的配置以及并发访问方式有关。让我们一一分析你提到的三种情况:
创建一千个schedule:
这种情况下,如果每个schedule都创建了自己的数据库连接并未正确关闭,可能导致连接池中的连接被快速耗尽。每个schedule都可能持有一个独立的数据库连接,而连接池的大小是有限的。如果连接没有被释放,连接池可能会在达到最大连接数后拒绝新的连接请求。
一个schedule循环一千次:
这样做已经减少了连接池中连接的数量,因为只有一个schedule在使用连接。然而,如果连接没有被正确关闭,仍然可能导致连接池问题。确保在每次数据库操作之后都正确关闭连接,最好使用try-with-resources或手动关闭连接,以释放资源。
多线程并发访问:
如果你将循环的逻辑拆分成多线程来执行,确保每个线程都使用独立的数据库连接,并在使用后正确关闭连接。如果多个线程共享相同的数据库连接,你可能会遇到并发访问的问题,需要考虑加锁等并发控制手段。
此外,如果你的应用中使用了连接池(例如HikariCP),确保连接池的配置足够大,以满足多线程的需求。你可以调整连接池的最大连接数等参数来适应并发情况。
在所有情况下,都要确保在使用完数据库连接后正确关闭连接,以释放资源并将连接返回到连接池。另外,监控数据库连接池的状态,了解连接池的使用情况,以及根据实际需求进行调整。
连接池 是 S.B.进程 这边的,总量有限;
假设CPU内核是 N ,一千个调度一起来,同时操作(运行中,CPU占用)的就有 N 个调度;
要考虑一次 SQL操作 的 响应时间-I/O,假设一次需要 M ms,线程在IO操作期间,挂起,新的调度开始执行(占用CPU),此时,就需要另外的 数据库连接——从连接池中获取,没有的话,报错——耗尽;要是前面调度的在 M ms 内完成了,连接可以被释放,进而重用;
对于第2、第3的改造,试试 JAVA本身的多线程工具【线程同步】了——现在同时多少个执行,执行完之前,不允许开启新的调度。
第一种: 使用springboot默认的连接池。直接创建1k个连接去操作数据库,连接池的默认数为10个,因此资源补充不上直接耗尽。。。压力中,
– CallMeEureka 10个月前第二种。一个线程循环1k次。每次都是拿一个连接用完放回。因此压力最小。
第三种: 1k次多线程跑与第一种方式理论上基本一样,资源耗尽。压力最大。