挂在等待查询的页面,耗费内存并花费2个小时才能失败

查看Fusion Reactor的附图,显示只是继续运行的页面。 时代已经进入了数百万人,我已经离开他们看看他们是否会完成,但那是当时只有2或3。

现在我得到了几十个从未完成的页面。 这是不同的查询,我看不到任何巨大的模式,除了它似乎只适用于我的7个数据库中的3个。

top显示的Coldfusion CPU使用率大约在70-120%之间,深入研究Fusion Reactor的详细信息页面显示所有build立时间都只用于Mysql查询。

show processlist没有任何exception,执行10 – 20个连接处于睡眠状态。

在这段时间内,许多页面都完成了,但是随着挂起的页面数量的增加,他们似乎永远无法完成服务器,最终只是返回白页。

唯一的短期解决scheme似乎是重启Coldfusion,这远非理想。

最近添加了一个Node.js脚本,每5分钟运行一次,并检查批处理csv文件,我想知道是否导致了一个窃取所有MySQL连接的问题,所以我禁用了(脚本没有connection.end ()方法),但这只是一个快速的猜测。

不知道从哪里开始,任何人都可以帮忙?

最糟糕的部分是永远不会超时的页面,如果他们这样做不会那么糟糕,但过了一段时间没有得到服务。

我正在使用Coldfusion和NodeJS作为我的主要脚本语言运行CentOS LAMP堆栈

非常长的请求永远不会失败

在实际发布之前进行更新

在写这篇文章的时候,我在禁用Node脚本并重新启动Coldfusion之后开始了这个工作,这个问题似乎已经消失了。

但是,我仍然想要帮助确定页面为何超时,并确认Node脚本需要connection.end()

也可能只发生在负载,所以我不是100%确定它已经消失

UPDATE

仍然有问题,我刚刚在Fusion Reactor中复制了当前长达70秒的查询中的一个,并在数据库中手动运行它,并在几毫秒内完成。 查询本身似乎不成问题。

另一个更新

其中一个页面的堆栈跟踪仍在进行中。 服务器在一段时间内还没有停止提供页面,所有的Node脚本都被禁用了

http://pastebin.com/D6ycJf3X

更多更新

今天我又多了几个 – 他们真的完成了,我在FusionReactor中发现了这个错误:

Error Executing Database Query. The last packet successfully received from the server was 7,200,045 milliseconds ago. The last packet sent successfully to the server was 7,200,041 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

甚至更多的更新

挖掘代码,我试图寻找“2小时”,“120”和“7200”,因为我觉得7200000毫秒的超时是太巧合。

我发现这个代码:

 // 3 occurrences of this createObject( "java", "coldfusion.tagext.lang.SettingTag" ).setRequestTimeout( javaCast( "double", 7200 ) ); // 1 occurrence of this <cfsetting requestTimeOut="7200"> 

引用这些代码行的4页很less运行,从未在2h +超时的日志中显示,并且位于密码保护区域中,因此无法被抓取(它们用于文件上载和CSV处理,现在移动到nodejs)。

这些设置是否可以通过一个页面设置,但存在于服务器中,并影响其他请求?

1)发布堆栈跟踪。

我保证他们将挂在Socket.read()(或类似的)

什么是occouring是到db的tcp连接的1/2是closures的,离开cf等待一个永远不会得到的响应。

在cf框和db之间有networking问题。

一般来说,Java db驱动程序在处理这个问题上很差


感谢您的堆栈跟踪

这证实了我的假设,即tcp连接closures的1/2。

我怀疑以下之一1)MySQL是在Linux上,并在TCP堆栈中有一个错误,所以你需要升级在这个盒子上的Linux – 是的,我已经看到这之前2)ColdFusion的是在Linux ..。 )3)在两个盒子之间或两者之间存在故障的电缆/硬件4)如果你正在运行窗口DISABLE TCP OFFLOAD !!!

3号)是艰难的。 你将需要在两个盒子上运行wireshark并certificate丢包。 更简单的解决scheme是将Rackspace虚拟机移动到不同的物理主机,看看它是否消失。 (有一个难得的机会,你的代码是非常糟糕的,你正在饱和CF盒和MySQL盒子之间的networking,但我不确定是否有可能写出糟糕的代码)

我已经花了更多的时间来研究这个问题,并且在networking问题的具体原因上添加了更多的细节,并且在Charlie Arehart的帮助下find了一个解决方法。

首先,networking连接被触发iptables restart的自动脚本中断。 这是更新可以访问服务器的IP地址列表,但是也打破了应用程序和数据库服务器之间的任何连接。

它更可能发生在页面较慢或运行频率较高的页面上,但与iptables restart代码重合的任何内容都会被切断。

Rackspace为我find了这个,并build议更改代码:

/sbin/service iptables restart

/sbin/iptables-restore < /etc/sysconfig/iptables

这会停止正在重新启动的服务,只适用于新的连接。

这是问题的根源,但真正的问题是Coldfusion,或者真正的JDBC底层不会停止等待数据库服务器的响应。

我不确定2小时超时是在哪里进行的(假设这是默认),但Charlie展示了一种在CFIDE连接string中设置较短时间的方法 – 这告诉CF在放弃数据库之前等待最长时间。

所以我们的连接string是:

__fusionreactor_name=datasourcename;connectTimeout=600000;socketTimeout=600000;

我不记得这些2的细节,但他们设置了一个毫秒的时间来等待,然后放弃db连接:

  • connectTimeout = 600000;
  • 了socketTimeout = 600000;

这个只是在Fusion Reactor中标记数据源 – 如果有的话,这对于在CF应用程序中发现问题非常有用。 如果你没有融合反应堆,那就留下这一点。

  • __fusionreactor_name = dsnapi;

你必须把这个应用到你的CFIDE中的每个数据源

显示连接字符串的CFIDE数据源面板