【问题标题】:Getting Too many Open Files Error in logs在日志中获取太多打开的文件错误
【发布时间】:2021-06-24 06:19:14
【问题描述】:

最近我们在生产中遇到“(打开的文件太多)”错误,这导致 Linux 机器上的 CPU 峰值非常高(98%),最终导致机器停机。我们必须重新启动机器才能将其恢复。

代码流程是这样的:-

使用来自 IBM-MQ 队列之一的消息 -> 开始处理它 -> 在 SQL-Server DB 中创建一些更新条目并提交事务。

我们使用 Hikari 进行连接池管理,值设置为 30

hikariConfig.setMaximumPoolSize(30);

在检查日志时,我发现了以下堆栈跟踪:-

2021-03-24T20:00:22.404 WARNING org.apache.catalina.loader.WebappClassLoaderBase Failed to open JAR [null]
java.io.FileNotFoundException: /opt/apache-tomcat-7.0.88/webapps/ROOT/WEB-INF/lib/HikariCP-2.5.1.jar (Too many open files)
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:219)
    at java.util.zip.ZipFile.<init>(ZipFile.java:149)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:130)
    at org.apache.tomcat.util.compat.JreCompat.jarFileNewInstance(JreCompat.java:221)
    at org.apache.catalina.loader.WebappClassLoaderBase.openJARs(WebappClassLoaderBase.java:3102)
    at org.apache.catalina.loader.WebappClassLoaderBase.findResourceInternal(WebappClassLoaderBase.java:3414)
    at org.apache.catalina.loader.WebappClassLoaderBase.findResource(WebappClassLoaderBase.java:1494)
    at org.apache.catalina.loader.WebappClassLoaderBase.getResourceAsStream(WebappClassLoaderBase.java:1722)
    at java.util.ResourceBundle$Control$1.run(ResourceBundle.java:2677)
    at java.util.ResourceBundle$Control$1.run(ResourceBundle.java:2662)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.util.ResourceBundle$Control.newBundle(ResourceBundle.java:2661)
    at java.util.ResourceBundle.loadBundle(ResourceBundle.java:1501)
    at java.util.ResourceBundle.findBundle(ResourceBundle.java:1465)
    at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1361)
    at java.util.ResourceBundle.getBundle(ResourceBundle.java:773)
    at com.ibm.mq.jmqi.JmqiException.buildMessage(JmqiException.java:428)
    at com.ibm.mq.jmqi.JmqiException.getMessage(JmqiException.java:543)
    at com.ibm.mq.jmqi.JmqiException.getMessage(JmqiException.java:515)
    at java.lang.Throwable.getLocalizedMessage(Throwable.java:391)
    at com.ibm.mq.jmqi.internal.JmqiTools.getExSumm(JmqiTools.java:947)
    at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiConnect(RemoteFAP.java:2282)
    at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiConnect(RemoteFAP.java:1294)
    at com.ibm.msg.client.wmq.internal.WMQSession.connect(WMQSession.java:387)
    at com.ibm.msg.client.wmq.internal.WMQSession.<init>(WMQSession.java:331)
    at com.ibm.msg.client.wmq.internal.WMQConnection.createSession(WMQConnection.java:909)
    at com.ibm.msg.client.jms.internal.JmsConnectionImpl.createSession(JmsConnectionImpl.java:896)
    at com.ibm.mq.jms.MQConnection.createSession(MQConnection.java:337)
    at org.springframework.jms.connection.SingleConnectionFactory.createSession(SingleConnectionFactory.java:437)
    at org.springframework.jms.connection.CachingConnectionFactory.getSession(CachingConnectionFactory.java:236)
    at org.springframework.jms.connection.SingleConnectionFactory$SharedConnectionInvocationHandler.invoke(SingleConnectionFactory.java:604)
    at com.sun.proxy.$Proxy195.createSession(Unknown Source)
    at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:192)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:475)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:526)
    at com.test.config.messaging.MainframeMessageProducer.lambda$sendMessageToQueueWithHeaders$0(MainframeMessageProducer.java:120)
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287)
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:164)
    at com.test.config.messaging.MainframeMessageProducer.sendMessageToQueueWithHeaders(MainframeMessageProducer.java:118)
    at com.test.config.messaging.MainframeMessageProducer.sendMessageToMainframeQueue(MainframeMessageProducer.java:101)
    at com.test.config.messaging.MainframeMessageProducer$$FastClassBySpringCGLIB$$f2d092d2.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
    at com.test.common.aop.RecordTimingAspect.recordTimingAspect(RecordTimingAspect.java:28)
    at sun.reflect.GeneratedMethodAccessor505.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
    at com.test.config.messaging.MainframeMessageProducer$$EnhancerBySpringCGLIB$$dc5ae691.sendMessageToMainframeQueue(<generated>)
    at com.test.posting.GDISPurchasePostServiceImpl.postMessage(GDISPurchasePostServiceImpl.java:315)
    at com.test.posting.GDISPostingService.processMessage(GDISPostingService.java:56)
    at com.test.posting.GDISPostingService$$FastClassBySpringCGLIB$$3c0c40af.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
    at com.test.common.aop.CorrelationIdAspect.correlationIdAdvice(CorrelationIdAspect.java:40)
    at sun.reflect.GeneratedMethodAccessor554.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
    at com.test.posting.GDISPostingService$$EnhancerBySpringCGLIB$$dd870248.processMessage(<generated>)
    at com.test.posting.GDISPostingMessageListener.onMessage(GDISPostingMessageListener.java:167)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:746)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:684)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:317)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:255)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1166)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1158)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1055)
    at java.lang.Thread.run(Thread.java:748)

我在这里感到困惑是什么导致了最大打开文件错误:-

  1. 是因为 Hikari CP,因为这是我们得到的第一行错误 (java.io.FileNotFoundException: /opt/apache-tomcat-7.0.88/webapps/ROOT/WEB-INF/lib/HikariCP-2.5 .1.jar(打开的文件太多))?
  2. 是因为 IBM-MQ 连接不可用吗?

【问题讨论】:

  • 为什么不增加操作系统上允许打开的最大文件数?
  • 听起来您正在打开文件,然后在使用后无法关闭它们。您是否查看过您的代码以确保您使用的是 try-with-resources 模式,以便包装文件句柄等内容的 AutoCloseable 类在超出范围时实际上会被关闭和处置?
  • @AttilaRepasi 这是我们在过去 3 年中第一次遇到问题,重新启动后一切正常。由于这是由其他团队管理的计算,因此在我们知道它的真正原因之前,增加最大连接数会很困难。
  • @AlwaysLearning 由于我们使用 Hikari 进行连接池和 Spring JPA 作为 ORM 工具,因此根据需要打开和关闭连接的 AFAIK 将由 Hikari CP 负责。我的理解正确吗?
  • 该堆栈跟踪显示它无法打开 .zip 存档文件(.jar 文件是具有不同扩展名的 .zip 存档格式)。您自己的代码是否打开任何从中读取或写入数据的文件?您自己的代码在使用这些文件后是否会关闭它们?在 Linux 上,您可能可以定期运行 lsof -u YourProcessUserName 以确保它保持打开的文件列表不会随着时间的推移而不断增长。

标签: sql-server ibm-mq spring-jms hikaricp


【解决方案1】:

您可以使用 lsof 命令列出打开的文件。 它产生大量输出,因此您需要捕获并后处理它(例如 grep 或排序) 您可以按 pid、userid、disk 等列出打开的文件。

你可以尝试 lsof > before wait... lsof > after 然后使用 diff 来查看差异

【讨论】:

    猜你喜欢
    • 2017-03-02
    • 2015-01-08
    • 1970-01-01
    • 2014-10-03
    • 2010-12-07
    • 1970-01-01
    • 2014-06-23
    • 2016-03-17
    • 1970-01-01
    相关资源
    最近更新 更多