JRun线程池configuration

我和我的团队一直在努力保持ColdFusion应用程序集群在过去6个月的较好的一段时间内保持稳定,而且效果甚微。 我们正在转向SF,希望能够find一些JRun的专家或新鲜的想法,因为我们似乎无法弄清楚。

设置:
在Windows Server 2003的IIS 6上,两个ColdFusion 7.0.2实例与JRun 4(w /最新更新)集群。两个四核CPU,8GB RAM。

问题:
每隔一段时间,通常一周一次的实例将完全停止处理请求。 它没有任何活动,我们必须重新启动它。

我们知道:
每当发生这种情况JRun的错误日志总是充满java.lang.OutOfMemoryError:无法创build新的本地线程

在阅读Macromedia / Adob​​e的JRun文档以及许多令人困惑的博客文章之后,我们或多或less地将其缩小到实例的jrun.xml中不正确/未优化的JRun线程池设置。

我们的jrun.xml的相关部分:

<service class="jrun.servlet.jrpp.JRunProxyService" name="ProxyService"> <attribute name="activeHandlerThreads">500</attribute> <attribute name="backlog">500</attribute> <attribute name="deactivated">false</attribute> <attribute name="interface">*</attribute> <attribute name="maxHandlerThreads">1000</attribute> <attribute name="minHandlerThreads">1</attribute> <attribute name="port">51003</attribute> <attribute name="threadWaitTimeout">300</attribute> <attribute name="timeout">300</attribute> {snip} </service> 

我已经在上周启用JRun的指标来收集与线程相关的数据。 这是让它login一周后的数据摘要。

平均值:

 {jrpp.listenTh} 1 {jrpp.idleTh} 9 {jrpp.delayTh} 0 {jrpp.busyTh} 0 {jrpp.totalTh} 10 {jrpp.delayRq} 0 {jrpp.droppedRq} 0 {jrpp.handledRq} 4 {jrpp.handledMs} 6036 {jrpp.delayMs} 0 {freeMemory} 48667 {totalMemory} 403598 {sessions} 737 {sessionsInMem} 737 

最大值:

 {jrpp.listenTh} 10 {jrpp.idleTh} 94 {jrpp.delayTh} 1 {jrpp.busyTh} 39 {jrpp.totalTh} 100 {jrpp.delayRq} 0 {jrpp.droppedRq} 0 {jrpp.handledRq} 87 {jrpp.handledMs} 508845 {jrpp.delayMs} 0 {freeMemory} 169313 {totalMemory} 578432 {sessions} 2297 {sessionsInMem} 2297 

任何想法,我们现在可以尝试吗?

干杯!


编辑#1 – >我忘了提到的事情:Windows Server 2003企业w / JVM 1.4.2(JRun)

最大的堆大小是1.4GB左右。 我们曾经有泄漏,但我们修复它们,现在应用程序使用大约400MB,很less更多。 最大堆大小设置为1200MB,所以我们没有达到它。 当我们确实有泄漏时,JVM就会炸毁,实例会自行重启。 这不是现在发生,它只是停止处理传入的请求。

我们认为这跟post有关: http : //www.talkingtree.com/blog/index.cfm/2005/3/11/NewNativeThread

抛出的Javaexception是OutOfMemorytypes,但实际上并不是说我们没有足够的空间,只是无法创build新的线程。 exceptiontypes有点误导。

基本上这个博客是说500作为activeHandlerThreads可能太高,但我的指标似乎表明,我们没有得到任何接近令我们困惑的地方。

那么,在进入JRunconfiguration细节之前,我们来看看一些更大的图片问题。

如果您在JRun错误日志中发现java.lang.OutOfMemoryErrorexception,那么您的内存不足。 没有为此赞成,请;-)。 你没有说你是在运行32位还是64位的Windows,但是你确实说你有8 GB的内存,所以这对于答案会有一些影响。 不pipe你运行的是32位还是64位的JVM(以及哪个版本),都会影响事物。 所以这些答案将帮助我们深入到底。

无论如何,你的应用程序内存不足。 由于以下一个或多个原因,内存不足:

  1. 你的应用程序正在泄漏内存。 您的应用程序所使用的某些对象不断被引用,因此永远不符合垃圾回收的条件 或者更糟 – 每个请求上创build的新对象都是由另一个对象永久引用的,因此永远不符合垃圾回收的条件。 正确的J2EE会话处理在这方面可能特别棘手。
  2. 处理每个并发请求(在configuration的并发请求级别)所需的内存量超过了JVM堆中可用的内存量。 例如,您的堆大小为1 GB,每个请求最多可以使用10 MB。 您的应用服务器已调整为允许150个并发请求。 (简单的数字,我知道)。 在这种情况下,如果您在加载时经历了100个或更多的并发请求(如果每个请求使用了满足请求所需的最大内存量),那么您一定会耗尽内存。

其他要记住的事情是:在32位Windows上,32位JVM只能分配大约1.4 GB的内存。 如果64位Windows上的32位JVM的限制小于任何32位进程的最大理论上的4 GB,那么我不记得我的头脑。

更新

我阅读了通过TalkingTree链接的博客post以及该post中链接的其他post。 我还没有遇到这种情况,但我确实有以下观察:JRUN指标logging可能不会logging您在峰值线程使用期间引用的“最大值”。 我认为它会以固定的,重复的间隔来logging指标。 这对于向您显示应用程序的平均性能特征非常有用,但在错误情况开始发生之前,它可能不会捕获JRUN的状态。

在不了解JRUN线程pipe理的内部工作的情况下,我仍然认为它确实是内存不足。 也许这并不是内存不足,因为你的应用程序需要在JVM堆上分配内存,而没有可用内存,但是内存不足,因为JRUN试图创build另一个线程来处理一个传入的请求,而支持另一个线程所需的堆内存wasn' t可用 – 换句话说,线程不是空闲的 – 它们也需要堆内存。

你的select似乎如下:

  1. 减less应用程序在每个请求中使用的内存量,或者 –
  2. 通过实验减lessJRUNconfiguration中的线程调整参数的值,使更多的线程排队等待处理,而不是同时运行,
  3. 减lessColdFusionpipe理员(请求调整页面,“最大并发模板请求数”字段)中的同时请求数

不pipe你追求什么select,我认为这里有效的解决scheme将是实验性的。 你将不得不做出改变,看看它对应用程序有什么影响。 你有一个负载testing环境,对吧?

尝试并减less最大堆大小。 每个线程都需要本地资源(以及java自己的东西)。 可用的虚拟AS是2GB; 1.2GB是为堆保留的。 部分剩余的800MB用于代码(Java的文本段和所有需要的DLL),然后JRE及其依赖关系和线程需要本地分配:默认情况下,每个线程保留1MB的AS被保留(虽然只是一个页面实际提交),100线程= 100MB(只为堆栈)。 现在在各个部分之间添加一些额外的空间,一些碎片… OOM 😉