批量导入时间过长导致Durid的空闲连接时间长自动关闭,如何解决?

技术背景:

Java、Spring全家桶、MySQL、Druid链接池

问题场景:

现在需要做一个批量退款功能,但因为最核心的微信、支付宝等三方退款是不支持的接口模式的批量退款,只有单次退款,这就导致我需要for循环去单次处理,导致处理时间较长,当批量处理1000个的时候,就会出现问题,Druid连接池会断开连接,导致数据没存到MySQL数据库中

discard long time none received connection. , jdbcUrl : jdbc:mysql://localhost:3306/
my_db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8, version : 1.2.5, lastPacketReceivedIdleMillis : 65682

里面的敏感数据已经清楚,但报错信息还是很清晰的

问题分析:

因为当数量较少时,是不会有这个问题,但当数量偏大了,就一定会出现这个问题,有没有在不改变Druid断开时长的方式,来解决这个问题。
也有想法说要不 用异步+分模块的方式来解决,但这样需要怎么做呢,分模块之后 怎么收集保持原有的顺序呢?
有没有老哥有经验啊?

阅读 1.1k
avatarAI BotBETA

对于你的问题,我有一些可能的解决方案。

首先,这个问题可能是由于你的数据库连接超时设置过短所导致的。在 Druid 连接池的配置中,有一个参数叫做 maxActive,它表示连接池中允许的最大活动连接数。如果这个值设置得太小,而你的批量操作又需要大量的数据库连接,那么就可能导致连接超时断开。

你可以尝试提高 maxActive 的值,以允许更多的连接同时处于活动状态。这可以解决由于大量并发连接而导致的连接超时断开问题。

其次,你提到想要采用异步+分模块的方式来解决这个问题。这是一个很好的思路,可以通过将大的批量操作分解为较小的任务,然后使用异步的方式进行处理。这样不仅可以避免连接超时的问题,还可以提高系统的吞吐量。

对于保持原有的顺序问题,你可以在每个任务完成后,将任务的结果存储到一个队列中。然后,在所有的任务都完成后,你可以按照队列的顺序依次处理结果。这样就可以保证结果的顺序与原始数据的顺序保持一致。

具体的实现方式可能会涉及到一些编程细节,比如如何将任务分解为较小的部分,如何异步处理这些任务,以及如何存储和按顺序处理结果等。如果你需要更具体的帮助,可以提供一些代码示例或者更详细的需求描述。

最后,你可能需要考虑使用批处理操作或者事务来处理这些数据。批处理操作可以减少与数据库的交互次数,提高处理效率。而事务则可以保证数据的一致性,避免在处理过程中出现数据不一致的情况。

希望这些建议能对你有所帮助!如果你还有其他问题或者需要更详细的解释,欢迎继续提问。

1 个回答

你可以尝试添加在spring.datasource 下 use-ping-method: false 这个属性
image.png

spring.datasource.druid.mysql.usePingMethod 是 Druid 数据库连接池的一个配置参数,用于指定是否使用 ping 方法来检测数据库连接是否有效。该参数的默认值为 false,即默认不使用 ping 方法。

在 Druid 数据库连接池中,检测连接是否有效的方式有两种:一种是执行 SQL 语句来检测连接是否有效,另一种是使用 ping 方法来检测连接是否有效。使用 ping 方法可以更快速地检测连接是否有效,但是在某些情况下,可能会出现误判。例如,如果数据库服务器反应较慢,ping 方法可能会将连接判定为无效,从而导致连接关闭。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题