当前位置: 首页 > 知识库问答 >
问题:

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

汪欣德
2023-11-16

技术背景:

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断开时长的方式,来解决这个问题。
也有想法说要不 用异步+分模块的方式来解决,但这样需要怎么做呢,分模块之后 怎么收集保持原有的顺序呢?
有没有老哥有经验啊?

共有2个答案

陆海阳
2023-11-16

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

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

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

韦欣德
2023-11-16

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

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

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

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

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

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

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

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

 类似资料:
  • 我正试图连接到mysql服务器,但这需要5秒钟。

  • 正如您所看到的,前两行之间有超过2分钟的间隔,这很可笑,尤其是考虑到这是一个非常小的应用程序。 在放弃自由配置文件之前,我可以做些什么来加快速度?

  • 我们在600个使用Spock的groovy文件中进行了大量测试。所有的testclasses都是从一个AbstractSpecification.groovy扩展而来,它注入了许多服务类和许多使用这些类的帮助器方法(Spring,Autowired)。 我们使用Eclipse,当然,对抽象类的每一次更改都会导致重新编译(构建工作区,调用Maven Project Builder)。但是在开发过程中

  • 我有一个在Tomcat7上运行的Spring3.0WebMVC应用程序。在应用程序启动时,我启动一个后台线程来加载内存缓存,其中包含来自数据库的记录。该线程从数据库加载所有数据通常需要一个多小时。在同一个应用程序中,我有一个@Controller注释类,它公开了一个REST接口,客户端可以通过该接口从加载的缓存中获取对象。 我们的要求之一是,在数据加载完成之前发出的任何REST请求都将立即向客户端

  • 我们正在spring boot(带有嵌入式tomcat)和spring Cloud上运行微服务。这意味着服务发现,定期的健康检查和响应这些健康检查的服务,……我们还有spring boot admin server用于监控,我们可以看到所有服务都运行正常。目前仅在测试环境中运行... 我们的一些微服务很少被调用(假设每两天调用一次),但是仍然有定期的健康检查。当这些服务的REST api在如此长的

  • 给出结果需要20多秒,而在mongo控制台中同样的查询需要不到一秒。 为什么会出现这种情况,如何减少速度差距?