我在“中”Amazon EC2 实例上的 Ubuntu 上运行 CF 9.0.1。CF 一直在间歇性地占用(每天几次......但特别是不孤立于高峰使用时间)。在这种时候,运行top让我得到这个(或类似的东西):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+COMMAND
15855 wwwrun 20 0 1762m 730m 20m S 99.3 19.4 13:22.96 coldfusion9
因此,它显然消耗了大部分服务器资源。在每次占用之前,我的 cfserver.log 中都出现了以下错误:
java.lang.RuntimeException: Request timed out waiting for an available thread to run. You may want to consider increasing the number of active threads in the thread pool.
如果我运行/opt/coldfusion9/bin/coldfusion status,我会得到:
Pg/Sec DB/Sec CP/Sec Reqs Reqs Reqs AvgQ AvgReq AvgDB Bytes Bytes
Now Hi Now Hi Now Hi Q'ed Run'g TO'ed Time Time Time In/Sec Out/Sec
0 0 0 0 -1 -1 150 25 0 0 -1352560 0 0
在管理员中,在Server Settings > Request Tuning下,同时模板请求的最大数量设置为25。所以到目前为止这是有意义的。我可以增加线程池来覆盖这些负载峰值。我可以做到 200。(我刚才做了测试。)
但是,还有这个文件/opt/coldfusion9/runtime/servers/coldfusion/SERVER-INF/jrun.xml。那里的一些设置似乎有冲突。例如,它写道:
<service class="jrunx.scheduler.SchedulerService" name="SchedulerService">
<attribute name="bindToJNDI">true</attribute>
<attribute name="activeHandlerThreads">25</attribute>
<attribute name="maxHandlerThreads">1000</attribute>
<attribute name="minHandlerThreads">20</attribute>
<attribute name="threadWaitTimeout">180</attribute>
<attribute name="timeout">600</attribute>
</service>
哪个 a) 具有较少的活动线程(这是什么意思?),和 b) 具有超过管理员中设置的同时请求限制的最大线程。所以,我不确定。这些独立的配置需要手动匹配吗?还是在进行更改时应该由 CF 管理员编写jrun.xml文件?唔。但也许这是不同的,因为大概 CF 调度程序应该只使用所有可用线程的一个子集,对吧?...所以我们总是有一些线程供真实用户使用?我们也有这个:
<service class="jrun.servlet.http.WebService" name="WebService">
<attribute name="port">8500</attribute>
<attribute name="interface">*</attribute>
<attribute name="deactivated">true</attribute>
<attribute name="activeHandlerThreads">200</attribute>
<attribute name="minHandlerThreads">1</attribute>
<attribute name="maxHandlerThreads">1000</attribute>
<attribute name="mapCheck">0</attribute>
<attribute name="threadWaitTimeout">300</attribute>
<attribute name="backlog">500</attribute>
<attribute name="timeout">300</attribute>
</service>
当我更改 CF Admin 设置时,这似乎已经改变......也许......但它是与我的新最大同时请求设置匹配的activeHandlerThreads ......而不是maxHandlerThreads,它再次超过了它。最后,我们有这个:
<service class="jrun.servlet.jrpp.JRunProxyService" name="ProxyService">
<attribute name="activeHandlerThreads">200</attribute>
<attribute name="minHandlerThreads">1</attribute>
<attribute name="maxHandlerThreads">1000</attribute>
<attribute name="mapCheck">0</attribute>
<attribute name="threadWaitTimeout">300</attribute>
<attribute name="backlog">500</attribute>
<attribute name="deactivated">false</attribute>
<attribute name="interface">*</attribute>
<attribute name="port">51800</attribute>
<attribute name="timeout">300</attribute>
<attribute name="cacheRealPath">true</attribute>
</service>
所以,我不确定我应该更改哪些(如果有的话)以及最大请求和最大线程之间的确切关系。此外,由于其中几个将maxHandlerThreads列为 1000,我想知道是否应该将最大同时请求数设置为 1000。必须有一些上限取决于可用的服务器资源......但我不确定是什么它是,我真的不想玩它,因为它是一个生产环境。
我不确定它是否与这个问题有关,但是当我运行ps aux | grep Coldfusion我得到以下信息:
wwwrun 15853 0.0 0.0 8704 760 pts/1 S 20:22 0:00 /opt/coldfusion9/runtime/bin/coldfusion9 -jar jrun.jar -autorestart -start coldfusion
wwwrun 15855 5.4 18.2 1678552 701932 pts/1 Sl 20:22 1:38 /opt/coldfusion9/runtime/bin/coldfusion9 -jar jrun.jar -start coldfusion
总是有这两个,永远不会超过这两个过程。因此,进程和线程之间似乎没有一对一的关系。我记得在我维护多年的 MX 6.1 安装中,在进程列表中可以看到额外的 CF 进程。当时在我看来,每个线程都有一个进程......所以要么我错了,要么版本 9 中的某些东西完全不同,因为它报告了 25 个正在运行的请求并且只显示这两个进程。如果单个进程可以在后台有多个线程,那么我会想知道为什么我有两个进程而不是一个?...只是好奇。
所以,无论如何,我在撰写这篇文章时一直在尝试。如上所述,我将最大同时请求数调整为 200。我希望这能解决我的问题,但 CF 再次崩溃(相反,它停滞不前并且请求开始超时......所以有效地“崩溃”了)。这一次,top 看起来很相似(仍然消耗超过 99% 的 CPU),但 CF 状态看起来不同:
Pg/Sec DB/Sec CP/Sec Reqs Reqs Reqs AvgQ AvgReq AvgDB Bytes Bytes
Now Hi Now Hi Now Hi Q'ed Run'g TO'ed Time Time Time In/Sec Out/Sec
0 0 0 0 -1 -1 0 150 0 0 0 0 0 0
显然,由于我增加了最大同时请求数,它允许更多请求同时运行……但它仍然使服务器资源最大化。
进一步的实验(重新启动 CF 后)向我表明,在大约 30-35 个“Reqs Run'g”之后,服务器变得无法使用,所有额外的请求都不可避免地超时:
Pg/Sec DB/Sec CP/Sec Reqs Reqs Reqs AvgQ AvgReq AvgDB Bytes Bytes
Now Hi Now Hi Now Hi Q'ed Run'g TO'ed Time Time Time In/Sec Out/Sec
0 0 0 0 -1 -1 0 33 0 0 -492 0 0 0
因此,很明显,增加最大同时请求数并没有帮助。我想归根结底是这样的:它有什么困难?这些尖峰来自哪里?流量爆发?在哪些页面上?在任何给定时间正在运行哪些请求?我想我只需要更多信息来继续故障排除。如果有长时间运行的请求或其他问题,我不会在日志中看到它(尽管我确实在管理员中选中了该选项)。我需要知道哪些请求正是导致这些峰值的那些请求。任何帮助将非常感激。谢谢。
〜日