我有一个运行大量数据库查询的PHP站点。使用某些参数组合,这些查询可能会长时间运行,从而触发丑陋的超时消息。我想根据我网站风格的其余部分用一个很好的超时消息替换它。
预测这类问题的通常答案:
“优化您的查询,以便它们不会运行这么久” - 我正在记录长时间运行的查询并对其进行优化,但我只是在用户受到影响后才了解这些查询。
< / LI>“增加PHP超时设置(例如set_time_limit,max_execution_time),以便长时间运行的查询可以完成” - 有时查询可以运行几分钟。我想告诉用户之前有问题(例如30秒后)。
“使用register_tick_function监视脚本运行的时间” - 这只在我的脚本中的代码行之间执行。当脚本等待数据库的响应时,不会调用tick函数。
如果它有帮助,该站点使用Drupal(具有大量自定义)构建,并且在PHP 5.2上使用MySQL 5在虚拟专用Linux服务器上运行。
答案 0 :(得分:3)
没有异步的mysql调用,也没有分支轻量级线程的范围。
虽然您可以将PHP代码拆分为两层,并在它们之间使用可以异步调用的连接,但这种方法的问题是,在上层放弃获取后,数据库层仍会尝试运行查询返回结果 - 可能会阻止其他用户使用DBMS。 (你更有可能得到更频繁的超时页面请求。)
如果您将超时处理推送到位于网络服务器前面的反向代理中,您将遇到同样的问题。
实现超时的最明智的地方是数据库本身 - 但AFAIK,mysql不支持。
所以接下来的选择是在PHP和数据库之间构建一个代理 - 这可能是自包含的 - 为每个请求生成2个lighweight线程(1个用于运行查询,第2个用作监视器以杀死第一个,如果它也需要但是这不仅需要在支持轻量级线程的lnaguage中编写代码,还需要定义与PHP通信的协议。
然而,对代理模型采用不同的方法 - 您可以使用proc_open生成单独的PHP进程并将stdout流设置为非阻塞 - 这样您的PHP可以继续运行并检查代理是否已运行查询。如果它超时,那么作为代理的父节点,它可以发信号通知它关闭(proc_terminate()),这应该停止在数据库上运行查询。
当然,这意味着很多开发工作。
设置一个或多个从属DBMS来运行慢速查询可能会更加简单 - 可能需要智能负载平衡。或者看看让慢速查询变得更快的其他方法 - 比如预先整合。
HTH
下进行。
答案 1 :(得分:0)
connection handling文档是您需要的。
基本上,您需要使用register_shutdown_function()注册关机功能。无论脚本是否已成功完成,用户是否已取消(或已超时),脚本完成时都会调用此函数。
然后,关闭函数可以调用connection_status()函数。如果connection_status()返回2(TIMEOUT)并且前一页是运行麻烦查询的页面,则可以将用户重定向到说“抱歉,但我们现在正在经历高服务器负载的页面。”< / em>或其他什么。
答案 2 :(得分:-1)
您的服务器是否使用APC,Memcache,Boost和Drupal Cache进行了调整?这些是非常好的替代路线。
否则,在Drupal中运行哪种脚本会导致这种情况?出于好奇,你在运行视图和面板吗?