【问题标题】:Tomcat behaves as if it's not threading requests, causes slow response timeTomcat 的行为就好像它不是线程请求一样,导致响应时间变慢
【发布时间】:2012-09-01 00:08:34
【问题描述】:

我看到了奇怪的行为,我不知道如何进一步了解并希望有人能提供帮助。

背景:我有一个查询需要很长时间才能返回结果,因此我没有让用户在请求时直接等待数据,而是定期通过 Timer 对象执行此查询并将结果存储在静态变量中。因此,当用户请求数据时,我总是从静态变量中提取数据,从而使响应几乎是即时的。到目前为止一切顺利。

问题:但是,我看到的行为是,如果我在后台(定时器)请求开始查询数据时请求数据,我的用户的请求会等待数据返回之前响应——强制用户等待。就好像 tomcat 的行为与线程同步(我知道不是——它只是看起来那样)。

这是在生产环境中,在大多数情况下,一切都很好,但对于用户来说,有时网站只是为他们挂起并且他们觉得它不可靠(嗯,在某种意义上它是)。

我所做的:由于对数据的请求是在静态方法中,我想“啊哈!线程已同步,这导致了延迟!”所以我把我所有的静态方法都拉了出来,删除了同步并强制每个调用实例化它自己的对象来检索数据(以保持线程安全)。静态变量的信号量也没有任何同步。

我还安装了 javamelody 来尝试了解正在发生的事情,但到目前为止还没有什么新鲜事。我注意到很多(大多数)线程处于“WAITING”状态,但它们也有 0ms 的用户和 CPU 时间,所以不要认为这指向任何东西(?)。

运行 Tomcat 5.5(无 apache 层)、struts 2、Java 1.5

如果有人知道为什么对静态变量的简单请求会挂起更长的后台进程,我将不胜感激!或者,如果您知道我如何获得洞察力,那也很棒。

谢谢!

【问题讨论】:

  • 听起来确实在某处有synchronized,或者在某处阻止了对您的对象的调用,从而停止了请求处理。 (如果没有,它就不是线程安全的)
  • 我同意,看起来是这样,但是这两个调用是完全独立的,它们唯一的共同点是一个结果更新一个静态变量,而另一个从它读取(并且顺序不对我来说很重要)并且调用的每个方法都是完全独立的。这是我困惑的本质——当两个单独的tomcat请求唯一的共同点是一个非同步(没关系)静态变量时,我根本看不到它们是如何相互依赖的.
  • 那个静态变量是什么类型的,你用它做什么?
  • 这是一个存储 bean 向量的哈希表。我快速查找所需的 bean 向量并将它们返回到我的 jsp 页面。这是即时的。
  • 只有一个进程(从计时器启动的那个)更新哈希表,所以我看不到那里的线程问题(我可能遗漏了一些明显的东西)...... Beans。 ..这很有趣...他们确实从返回缓存数据的单例数据服务中读取数据,但我需要确保这不是罪魁祸首(我不相信它是,但有可能) - - 感谢这个(现在很明显)的想法......好吧,只是看看豆子,我没有看到任何会挂起它的东西 - 这一切都很简单。

标签: java tomcat5.5


【解决方案1】:

一种可能的解释是,由于长时间运行的查询导致数据库锁定(或其他原因),线程实际上在数据库级别阻塞。

弄清楚发生了什么的方法是找出被阻塞的线程阻塞的确切位置。可以通过向 JVM 发送 SIGQUIT(或等效项)来生成线程转储,并包含所有 Java 线程堆栈的堆栈跟踪。或者,您可以通过附加调试器等来获得相同的信息(以及更多信息)。无论哪种方式,每个堆栈顶部框架的类名和行号应该允许您查看源代码并(至少)弄清楚正在发生什么样的锁定或阻塞。

【讨论】:

  • 感谢斯蒂芬为此...我在eclipse中,但该过程在tomcat中。也就是说,当 tomcat 没有响应时,我没有可以使用的断点。你的意思是我应该在每次调用时对每个线程进行完整的堆栈跟踪吗?似乎我的下一个问题是试图从所有数据中找出意义。
  • Eclipse 调试器应该允许您检查 Tomcat 服务器的堆栈。您可能必须先从调试器中暂停它。或者,从命令行运行 Tomcat,并向其发送 SIGQUIT。
  • “你的意思是我应该在每次调用时对每个线程进行完整的堆栈跟踪吗?”。请重读我写的内容。 “似乎我的下一个问题是试图从所有数据中找出意义。” 显然(!!)您只需要为典型的堆栈执行此操作。但是,是的,您确实需要了解足够多的数据才能弄清楚发生了什么。 (如果编程/调试很容易,他们可以用你一半的薪水来做汉堡脚蹼……)
【解决方案2】:

对于那些想知道的人,我最终找到了 VisualVM (http://visualvm.java.net/download.html)。这是完美的。我像往常一样从 Eclipse 运行 Tomcat,它出现在 VisualVM 客户端中。鼠标右键单击 tomcat 图标,选择 Thread Dump,然后,砰,我搞定了。

感谢大家的帮助和指向正确方向的指点!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 2019-10-19
    • 2017-09-10
    • 1970-01-01
    相关资源
    最近更新 更多