该请求已超过允许的时间限制& Java Heap Space Null错误

时间:2016-10-10 20:52:12

标签: java mysql coldfusion jvm

我知道这个话题似乎已经多次讨论了,但我尝试了所有提到的方法都无济于事。

我一直在收到错误:

  

请求已超过允许的时间限制标记:CFQUERY   
第152行发生了错误。

以及

  

Java堆空间null
在第-1行发生错误。

在同一个html页面上。

我认为Java堆空间错误导致超时,反之亦然。

发生超时的程序是

        <CFQUERY DATASOURCE="#datasource#" USERNAME="#username#" PASSWORD="#password#" NAME="myQuery" CACHEDWITHIN="#CreateTimeSpan(0,0,5,0)#">
    SELECT tableA.productid, tableA.userid, tableA.salesid, tableA.productname, tableA.price, tableA.units, tableA.currency, tableA.terms, tableA.description, tableA.pic, tableA.minorder, tableA.salesid, tableB.id, tableB.company, tableB.city, tableB.state, tableB.country, tableB.contact, tableB.skype
    FROM tableA LEFT OUTER JOIN tableB
    ON tableA.userid = tableB.userid
        WHERE tableA.category = <cfqueryparam value = "#cat#" cfsqltype = "cf_sql_integer" maxLength = "2">
        ORDER by tableA.ranks DESC
        </CFQUERY>

我不知道如何进一步优化&#34;?它只检索大约28,000个结果记录, 2百万。我正在使用MySQL数据库。

我已将MaxPermSize从256MB增加到512MB,但似乎问题仍然存在,特别是当搜索引擎来到网站进行索引时。我在具有6GB RAM的服务器上运行CF9。以下是我在CF中的一些设置:

  • 最小和最大JVM堆大小都设置为512MB。
  • 超时请求(秒)设置为60
  • JVM版本1.7.0_67
  • JVM参数:
      

    -server -Dsun.io.useCanonCaches = false -XX:-UseGCOverheadLimit -XX:MaxPermSize = 512m -XX:+ UseParallelGC -Xbatch -Dcoldfusion.rootDir = {application.home} /../ -Dcoldfusion.libPath = {application.home} /../ LIB

欢迎任何建议。提前谢谢。

附加信息:

  1. 共有26类产品
  2. 每个类别都有20-50K记录并且每天都在增加
  3. 人们可能会或可能不会在白天的不同时间访问所有26个不同的类别
  4. 并非所有类别每天都会更新,但某些类别

1 个答案:

答案 0 :(得分:3)

在20个类别中,每个类别有20-40k个产品,行数未知,您可以在数据缓存方面做出一些真正的架构决策(如果使用缓存)。目前,每个category id参数都是该查询的唯一缓存,其生存时间为五分钟,占用了一定量的堆空间。此外,它必须在请求期间从缓存中复制出来并消耗内存,直到可以收集它为止。另请注意,permgen与堆大小无关。

我建议不要缓存以查看数据库服务器如何通过仅询问该页面的记录来处理它。内置查询缓存非常具有情境性,这不是其中之一。直到您意识到产品描述和其他大型文本块各为半兆,才能看到30k记录。如果你可以在任何具有强大目录的典型商业网站上,我强烈建议至少使用一堆或两个堆。 (你说“我在具有6GB RAM的服务器上运行CF9。”希望其中一些可以免费分配给JVM)。在这种情况下,更多的内存只会将问题推迟到以后的日期,如果有的话。

另外,将permgen拉回到256. 512 permgen非常高,即使对于大型企业应用程序也是如此。

以下是您的应用在请求进入时的当前功能。

  1. 点击查询代码并返回结果
    1. 缓存命中 - 结果从缓存中复制出来,浪费了大量的兆字节
    2. 缓存未命中 - 结果从数据库中流入,耗费了大量的兆字节,并且还被复制到缓存区域(但是您避免了数据库加载时间以及传输时间,我怀疑大部分时间都花在了转移而不是查询)
  2. 您使用了一小部分查询
  3. 查询是垃圾回收
  4. 在轻负载下,您的服务器可能几乎没有跟上。谁知道您的缓存区域能够避免流失的频率。

    补充跟进:

    听起来你只是为了分页的行数来做这一切。实际上,您可以将总行计数放入查询中,该查询仅将一个页面的记录作为子查询返回。如果要分成两个查询 - 一个用于行计数,另一个用于此行的记录,则前者是缓存的有力竞争者。数据不会经常变化,如果确实如此,那么如果你稍稍落后则无所谓。另外,它非常小,实际上有意义地缓存而不是一直询问DB。