代码之家  ›  专栏  ›  技术社区  ›  user102008

如果有一个CGI在输出数据之前运行了几分钟,而Apache超时了,该怎么办?

  •  1
  • user102008  · 技术社区  · 14 年前

    我有一个CGI脚本,需要很长的时间来执行。长话短说,它需要处理大量数据,运行一堆缓慢的命令,并进行一些缓慢的web查询,在此期间它不输出任何东西,当它完成时,它最终以json格式输出结果。运行需要几分钟的时间,这比ApacheWeb服务器的httpd.conf中设置的超时指令要长。

    我无权为整个服务器上的每个人全局更改该超时值。我想可能会在每个目录中使用.htaccess文件覆盖它,但是看起来timeout指令不在.htaccess上下文中,所以这无法完成。据我所知,我的脚本必须不断地输出数据,如果它没有输出超时秒数的数据,apache就会放弃。

    我在apache中遇到以下错误: (70007)The timeout specified has expired: ap_content_length_filter: apr_bucket_read() failed

    我能做什么?

    3 回复  |  直到 14 年前
        1
  •  1
  •   David Z    14 年前

    好吧,为了提供愚蠢的简单解决方案,为什么不让脚本在工作时偶尔产生一些输出呢?你可以每几步打印“处理…”,或者如果你想更有创意,让它打印一些状态更新来指示它在做什么。或者如果你担心无聊,就一行一行地打印出一首有趣的诗。(有点让我想起 http://pages.cs.wisc.edu/~veeve/404.html )

    如果你不想这样做,我接下来想到的是使用异步处理。基本上,您必须从cgi脚本生成一个单独的进程,并在该单独的进程中执行冗长的处理。主cgi脚本本身只输出一个简单的html页面,说明进程正在工作,然后退出。该html页面还必须包含一些逻辑,以便定期检查服务器上的后台进程是否已完成。可能是 <meta http-equiv="refresh" ...> html元素,或者可以使用ajax。

        2
  •  1
  •   user102008    13 年前

    我想出了一个解决办法。

    我会开始输出一个虚拟的http头,比如 Dummy: ... ,我可以把我想要的任何数据作为头的值,它不会影响其余的输出。所以我会每分钟输出一个字符到那个虚拟值,防止它超时。当我准备好了,我可以打印一个行返回,然后继续打印我的(真实的)http头和文档的内容。

        3
  •  0
  •   Peter Tillemans    14 年前

    一个非常务实的方法可以是开始一个背景工作,并通过电子邮件向客户回复。1o-1他们宁愿这样,也不愿整个下午都打开浏览器窗口。