日志警告:检测到线程饥饿或时钟跳跃(housekeeper delta = springHikariConnectionPool)

124

我正在使用 HikariCP 2.4.6,在 Tomcat 8 启动时,我收到了一个警告信息:

01-Aug-2016 11:18:01.599 INFO [RMI TCP Connection(4)-127.0.0.1] org.apache.catalina.core.ApplicationContext.log Initializing Spring FrameworkServlet 'Spring MVC Dispatcher Servlet'
[2016-08-01 11:18:01,654] Artifact blueberry:war exploded: Artifact is deployed successfully
[2016-08-01 11:18:01,655] Artifact blueberry:war exploded: Deploy took 33,985 milliseconds
Aug 01 2016 11:26:52.802 AM [DEV] (HikariPool.java:614)
WARN : com.zaxxer.hikari.pool.HikariPool - 9m13s102ms - Thread starvation or clock leap detected (housekeeper delta=springHikariConnectionPool).

我没有看到任何其他与从数据库读写相关的错误或问题。这个是需要担心的吗?我尝试搜索了一下,但没有结果。

我们还在使用 Hibernate 4.3.8.Final 连接 MySQL 5 和 MySQL 5.1.39 连接器以及 Spring 4.1.0.RELEASE。我们正在努力升级到 Hibernate 5 并查看是否会解决此问题,但不知道这是否重要。

9个回答

152

另一个原因是如果您在本地运行应用程序并且电脑进入睡眠状态,这种情况下您无需进行任何配置。


1
虽然这是一个完全合理的原因,以及本页上提到的其他原因,但我想知道,为什么它被记录为警告?如果它只是一条信息,很可能这个经常被搜索的SO页面甚至不会存在。 - ikaerom
PR已添加:https://github.com/brettwooldridge/HikariCP/pull/2038 - ikaerom
1
这正是我的问题,我在本地的 Mac 上运行应用程序。 - nxG
我也遇到过这种情况。我同意应该将其设为警告,因为我们始终需要注意生产环境中可能出现的问题。所以,这是关于休眠的警告,无论是机器还是我们的服务线程。或许可以增加一些额外的信息,比如“检查机器是否已挂起”。 - Thiago Sperandio

102

以下是关于时钟跳秒检测可能合理发生的概述。引用Brett Woolridge的外部链接:

这段代码在管家线程上运行,每30秒执行一次。如果您使用的是Mac OS X,则clockSource是System.currentTimeMillis(),其他平台则为System.nanoTime()。理论上两者都是单调递增的,但各种因素可能会影响这一点,例如NTP服务器。大多数操作系统都设计了处理NTP时间调整以保留时间流向前的幻象。
这段代码的意思是,如果时间倒退(现在<之前),或者时间“向前跳跃”超过两个管家周期(超过60秒),那么可能发生了奇怪的事情。
可能出现以下几种情况: 1. 您可能正在虚拟容器(VMWare、AWS等)中运行,由于某种原因无法维护时间流向前的幻象。 2. 由于管家线程中还有其他事情发生,特别是关闭空闲连接,因此有可能由于某些原因关闭连接会阻塞管家线程超过两个管家周期(60秒)。 3. 服务器非常繁忙,所有CPU都被占用,导致线程饥饿,防止管家线程运行超过两个管家周期。
考虑到这些情况,也许您可以提供额外的上下文。
编辑:请注意,这基于HikariCP 2.4.1代码。确保您运行的是最新版本。
(最新代码中警告语句的参数似乎也已经更新。)

110
当你在调试应用程序时,在一个断点上等待超过两个清理周期(60秒)时,也会出现原因3。在继续进行进程后,Hikari会发出像上面问题中那样的警告。 - GreenTurtle
3
这是我使用IntelliJ的情况。谢谢。 - Luciano Brum
1
添加一个新情况,发生在我身上:我正在使用Docker部署多个容器。其中一个容器包含SpringBootApplication,它使用Spring JPA和HikariCP。问题出现在Docker在容器之间平衡资源时,在这个特定的容器中减缓了housekeeping周期的执行速度。 - Rigoberto Peña
3
或者,你正在使用笔记本电脑,它进入了睡眠状态。 - Greg
@RigobertoPeña:你知道怎么解决这个问题吗? - Rabhi salim

11

导致这种情况发生的另一个原因是过度的垃圾回收,当垃圾回收在两个housekeeping线程之间运行更长时间时,试图释放一些内存(例如,当应用程序线程正在运行“select”查询时)。由于GC阻塞了所有应用程序线程,包括housekeeping线程,因此我怀疑是由于此原因导致了“跳跃”时钟。


我遇到了完全相同的问题。你有解决方案吗?- https://stackoverflow.com/questions/73025068/issue-post-running-select-query-java-lang-outofmemoryerror-gc-overhead-limit-e - tez
是的,在内存不足发生之前是相同的消息。 - whatswrong

7

我在AWS T2微型1GB RAM实例中使用Spring Boot MySQL时遇到了问题。经过一小时的努力,没有任何进展,发现CPU使用率接近100%。然后我将实例改为T2中型,拥有4 GB RAM和2个虚拟CPU。之后我就没有遇到任何问题了。


6
我遇到了这个问题,是因为我的实体类hashCode方法中出现了无限循环。
两个实体类之间存在OneToMany的关系,并且我使用了Lombok的@Data注解,它自动生成了equalshashcode的实现,同时对每个属性调用了hashCode()方法,导致了无限循环。

4

当我在Linux机器上运行我的Spring Boot微服务应用程序时,遇到了同样的问题。经过一些调查发现,服务器只有8GB内存。将内存(RAM)增加到16GB解决了我的问题。


1
我在AWS EC2上遇到了这个问题。
看起来AWS移动了,或者至少重新启动了我的EC2实例,因为我相信CPU和内存使用率非常高。看起来AWS认为EC2开始出现故障,因此移动了它或者做了类似的操作。
这导致进程在虚拟机从一台机器移动到另一台机器时冻结了一段时间,我遇到了这个问题。
我可能对原因有所误解,但是错误似乎经常发生,只有在资源使用率长时间非常高的情况下才会发生。
解决方案:减少或限制CPU和/或内存的消耗,或者切换到更好的硬件。

0

我停止了所有的服务并重新启动,这也解决了问题。


2
这不太可能永久解决问题。请看我的答案。 - riddle_me_this

0
如果这是发生在你的Spring Boot应用程序启动时
org.springframework.data.repository.config.RepositoryConfigurationDelegate : 
Bootstrapping Spring Data JPA repositories in DEFERRED mode.

然后使用以下程序参数运行您的应用程序

--spring.data.jpa.repositories.bootstrap_mode=default

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接