彩票走势图

PHP与504服务器错误

原创|行业资讯|编辑:龚雪|2014-01-06 09:45:56.000|阅读 575 次

概述:如果你的web应用或服务必须按需在服务器端执行一个可能很巨大的处理过程,本文则正好适合你。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

背景:

当我们的页面调用服务器动作,基本的php脚本比指定于超时服务器参数需要更多的时间,可以确定接下来的响应将是504(超时)服务器错误。如果你有其它选择得到同样的方法来改变应用结构或者UI体验(没有损坏它),我们建议您让它在没有多线程、shell calls或者第三方类的情况下运行。

建议使用paging和multipetition技术,有如下优点:

  • 它能相对简单地执行。你可以移植你的整块脚本而无需对代码做太多改变。
  • 常规执行上易于调整。有了这个技术,世界时间的执行是与页面大小成反比的,但很容易调整以获得良好的用户体验。
  • 你可以使用一个进度条来显示进程状态中所有你想要的细节,只是显示细节越多,越耗性能。

使用这个模式的缺点:

  • 不兼容原子进程。如果你的脚本必须一直被执行(在一个全局事务中)或者调用另一个你完全没有控制的脚本,你也许不会用这个技术。在这种情况下,你可能会考虑从PHP移植你的服务端应用到允许多线程(如.NET或JSP等等)的框架作为后台进程。

正如你所见的,这个技术并非所有情况都适用,但对于相当多的问题来说,它是个完美的解决方案。

使用代码:

首先是考虑如何将我们的任务分成尽可能小的逻辑片段。这些将被视为元素。我们将需要在每个请求中用到所有这些元素,但只有页面上的元素是需要的,是被处理的。

举个例子,我们将导入一个csv文件到数据库。以下是处理页面的函数脚本:

 

<?php
$path = '/userFiles/import.csv';     /* Local path to file */
$page = $_POST["page"];              /* Page to process (from JavaScript) */
$pageSize = 1000;                    /* Number of lines to process by page */
$first = $pageSize * $page;          /* First line to process. */
$line = 0;                           /* Current line. */
$processed = 0;                      /* Number of lines currently processed. */

/* Begins to read the CSV */
$file = fopen($path, "r");          
while ($lineStr = stream_get_line($file, 65536, "\n")) {
    if ($line >= $first) {    /* Only if current line is within the requested page */

                /* Process this line */
        insertLineInDatabaseOrDoAnyHeavyThingWithIt($line, $lineStr);  

        $processed ++;
        if ($processed = $pageSize) break;     /* Page end */        
    }        
    $line ++;    
}    
fclose($file);     

/* Returns number of processed lines */
echo $processed;

这是服务端,下面则是JavaScript客户端:

 

function import() {
    pageImport(0);     // Launch first page 
}

function pageImport(page) {
    $.post("/import.php", {   // Calls our php script asynchronously using jQuery
    page: page
    }, function(data) {   // Callback
    if (data > 0)
        pageImport(page + 1);    // Lines were processed so go on with next page
    else
        alert("Work finished");  // No more lines processed, so we have finished.
    });
}

两种方式都需要:第一种启动第一页,第二种递归调用自身处理下一个页面知道没有更多的记录。不难想象如何用JSON执行一个进度条以在相同的响应中返回已处理的行和总的页数。

注意点:

$pageSize越小,出现504错误的可能性就越小,但需要更多时间来完成整个进程,因为在每个请求上我们读取当前页之前的所有CSV行。$pageSize的最优质的是尽可能大却又耗费比服务器所定义的超时更少的时间来完成一页。举个例子,如果我们的超时定义为60秒,处理一页应该需要45到50秒或更少。通过浏览器上的F12开发者工具,很容易猜到这一点。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:慧都控件网

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP