Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
tomcat中的Java web应用程序会定期冻结_Java_Spring_Tomcat_Web Applications - Fatal编程技术网

tomcat中的Java web应用程序会定期冻结

tomcat中的Java web应用程序会定期冻结,java,spring,tomcat,web-applications,Java,Spring,Tomcat,Web Applications,我的Java web应用程序运行Tomcat(7.0.28)时会周期性地失去响应。我希望得到一些可能的罪魁祸首的建议(同步?),以及一些推荐的工具,以收集更多关于崩溃期间发生的事情的信息。我积累的一些事实: 当web应用程序冻结时,tomcat会继续向应用程序提供请求线程,但应用程序不会释放它们。线程池将填满到最大值(当前为250),随后的请求将立即失败。在正常操作过程中,活动线程数不得超过2或3个 当问题发生时,我们的tomcat或web应用程序日志中不会记录任何类型的错误或异常 通过tom

我的Java web应用程序运行Tomcat(7.0.28)时会周期性地失去响应。我希望得到一些可能的罪魁祸首的建议(同步?),以及一些推荐的工具,以收集更多关于崩溃期间发生的事情的信息。我积累的一些事实:

  • 当web应用程序冻结时,tomcat会继续向应用程序提供请求线程,但应用程序不会释放它们。线程池将填满到最大值(当前为250),随后的请求将立即失败。在正常操作过程中,活动线程数不得超过2或3个

  • 当问题发生时,我们的tomcat或web应用程序日志中不会记录任何类型的错误或异常

  • 通过tomcat管理web应用程序在我们的应用程序上执行“停止”,然后执行“启动”,立即解决了这个问题(直到今天)

  • 最近的频率是一天两到三次,尽管今天更糟,可能是20次,有时不会立即恢复生机

  • 问题只在工作时间出现

  • 这个问题不会发生在我们的登台系统上

  • 当问题发生时,服务器上的处理器和内存使用率保持不变(并且相当低)。Tomcat报告了大量可用内存

  • 当问题发生时,Tomcat会继续响应。管理web应用程序工作得非常好,tomcat继续向我们的应用程序发送请求,直到池中的所有线程都被填满

  • 当问题发生时,我们的数据库服务器保持响应。我们使用Spring框架进行数据访问和注入

  • 问题通常发生在使用率较高时,但使用率从来没有异常高的峰值

  • 问题历史:大约一年半以前也发生过类似的事情。在多次更改服务器配置和代码后,这个问题直到大约一个月前才消失。在过去几周内,这种情况发生得更为频繁,平均每天2到3次,有时是连续几次

  • 我发现了一些服务器代码可能不是线程安全的,并对此进行了修复,但问题仍然在发生(尽管不太频繁)。这是非线程安全代码可能导致的问题吗

更新:有几篇帖子建议使用数据库连接池耗尽,我在那个方向进行了一些搜索,找到了另一个,它解释了我遇到的几乎所有问题

显然,在Apache的BasicDataSource实现中,maxActive和maxIdle连接的默认值分别为8。此外,maxWait被设置为-1,因此当池耗尽并且新的连接请求进入时,它将永远等待,而不会记录任何类型的异常。我仍然要等待这个问题再次发生,并在JVM上执行jstack转储,以便分析这些信息,但看起来这就是问题所在。它唯一没有解释的是为什么应用程序有时无法从这个问题中恢复。我想这些请求有时会堆积起来,一旦它落后了,就永远赶不上了

更新II:我在崩溃期间运行了一个jstack,发现了以下大约250个(最多线程):

"http-nio-443-exec-294" daemon prio=10 tid=0x00002aaabd4ed800 nid=0x5a5d in Object.wait() [0x00000000579e2000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:485)
        at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1118)
        - locked <0x0000000743116b30> (a org.apache.commons.pool.impl.GenericObjectPool$Latch)
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
        at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
        at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:573)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:666)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:674)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:718)

我已经将maxActive设置为-1(无限),maxIdle设置为10。我将监视一段时间,但我猜这是问题的结束

根据经验,您可能需要查看数据库连接池的实现。可能您的数据库容量很大,但应用程序中的连接池仅限于少量连接。我记不起细节,但我似乎记得有一个类似的问题,这是我改用它的原因之一,我发现它在负载测试中非常快速和可靠

尝试下面建议的调试后,尝试增加池中可用的连接数,看看这是否有任何影响

我今天发现一些服务器代码可能不是线程安全的, 我对此进行了修复,但问题仍然存在 (尽管不那么频繁)。这就是我们所面临的问题吗 非线程安全代码会导致什么


这取决于线程安全的含义。在我看来,您的应用程序似乎正在导致线程崩溃。您可能希望在JVM配置为允许调试器连接的情况下运行您的生产环境,然后使用JVisualVM、JConsole或其他分析工具(您的工具包在IMO中非常优秀)来了解您拥有的线程以及它们在等待什么。

kill-3
是您的朋友。运行此命令并查看线程转储。您可能需要查看信息分组的线程转储分析器()。在没有任何其他信息的情况下(需要线程转储!):DB连接池耗尽。这正是发生在我身上的情况,webapplication增长太大,最大连接数太低,等待时间不精确,线程总是不断堆积,服务器就会冻结。增加了max cons,并在max wait上设置了一个特定的时间,现在我只是在监视,但服务器运行正常。谢谢你的小教程。是的,BoneCP rocks。commons dbcp太差劲了。Tomcat 7附带了一个dbcp,但要使用它,驱动程序必须可以从Tomcat-jdbc.jar所在的类加载器中访问。我不想每次安装新的Tomcat时都麻烦地将驱动程序jar放在Tomcat lib目录中。Redsonic:不是这样的。如果您的
数据源
是在上下文中定义的,而不是在上下文之间共享的JNDI资源,那么它可以位于上下文的类路径中(即在.war中)。这就是我在生产系统中使用它的方式。我没有测试自己。我报告了tomcat 7文档中的内容。那么,在这种情况下,它也是一个选项:)
 org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:114)
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
        at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
        at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)