嘗試在新的共享服務器帳戶上運行一些PHP腳本,腳本經常掛起並超時而沒有錯誤消息。只有在使用Web開發者控制檯運行Chrome中的腳本時,我纔會得到一些提示:「net :: ERR_INCOMPLETE_CHUNKED_ENCODING」就是這樣說的。錯誤:在PHP腳本中不完整的塊編碼
Fiddler2略有更具體:
Fiddler.Network.ProtocolViolation - [#165]傳輸編碼:分塊的響應沒有用正確的零大小的塊終止。
...和:
Fiddler.Network.ProtocolViolation - [#165] [HTTPLint#M012該HTTP響應分塊體是不完全的;最有可能缺乏最終的0尺寸塊。
我做了一個測試腳本來演示這個問題。它所做的只是隨機20-60秒的sleep(),然後顯示一個隨機字符串。默認情況下爲10次迭代。
但是這個託管服務提供商的服務檯一直堅持認爲它與php環境中的60秒超時有關,我知道這是hogwash。所以我放了第二個測試腳本,它使用Ajax連續多次調用另一個腳本。再一次,它是簡單的骨頭,只是一個睡眠(),隨機時間在40到55秒之間,然後生成並顯示一個短的隨機字符串。
因此,執行永遠不會超過60秒。但它仍然保持失敗,儘管在Chrome控制檯中xhr調用的「net :: ERR_EMPTY_RESPONSE」而不是「net :: ERR_INCOMPLETE_CHUNKED_ENCODING」。
當我向他們展示這件事時,他們實際上承認存在一個問題,這感覺像是一場勝利。但它是短暫的。第二天,他們回來說,很抱歉,他們無法弄清楚是什麼原因造成的,他們無能爲力,我是否考慮升級到vps?
我已經變得有點癡迷了。我想知道這究竟是什麼造成的。
第一個測試腳本代碼中,我寫道:
<?php
set_time_limit(3600);
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
function generateRandomString($length = 10) {
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[mt_rand(0, $charactersLength - 1)];
}
return $randomString;
}
isset($_REQUEST["limit"]) ? $limit = $_REQUEST["limit"] : $limit = 10;
echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">';
echo "<title>Test Script</title></head><body>";
//ob_start();
echo "<br><br>A random delay between 20 and 60 seconds will be generated, then a randomly generated string will be displayed<br>The default limit on iterations is ten<br>When the script terminates normally, the phrase \"test complete\" will be output at the bottom<br><br>";
flush();
for ($i = 0; $i < $limit; $i++) {
$delay = mt_rand (20, 60);
echo "<br><br><br>iteration ".($i+1)." - script will now sleep for $delay seconds";
flush();
sleep ($delay);
echo "<br><br>Here is a random string:<br>";
$length = mt_rand (50, 100);
echo generateRandomString($length);
flush();
}
echo '<br><br>...test complete</body></html>';
ob_end_flush();
?>
你可以去這個頁面:http://www.scripttest1.cu.cc/test_script.php看到自己時,它在此服務器上運行會發生什麼。
第二個測試腳本代碼:
<?php
set_time_limit(600);
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
isset($_REQUEST["limit"]) ? $limit = $_REQUEST["limit"] : $limit = 15;
isset($_REQUEST["longorshort"]) ? $longorshort = $_REQUEST["longorshort"] : $longorshort = "long";
$start = 1;
echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">';
echo "<title>Test Script 2</title></head><body>";
echo '<script src="test_script_js7.js"></script>';
echo "
<br>Clicking the button below will start the script running
<br>The script called via XMLHttpRequest will generate a random delay between 40 and 55 seconds (5-10 seconds if \"longorshort\" is set to \"short\" in the url string), then a randomly generated string will be displayed in the table on the bottom
<br>The default limit on iterations is fifteen
<br>When the process terminates normally, the phrase \"test complete\" will be output in the \"Main Info\" cell
<br><b>The script called via XMLHttpRequest will <u>never take more than 60 seconds</u> to complete processing</b>
";
//echo "<img src=http://nzbstar.info/download_batch.png onclick=\"getter($limit, '$start', '$longorshort')\"><br>";
echo "<br><img src=start.jpg onclick=\"getter_outer($limit, '$start', '$longorshort')\"><br><a href=\"javascript:master_switch();\">click here to abort</a> ";
echo "<table border=1><tr>";
echo "<td valign=top><div id=main_info>Main Info:</div></td>";
echo "<td valign=top><div id=iteration>Iterations:</div></td>";
echo "<td valign=top><div id=message>Messages:</div></td>";
echo "</tr></table>";
echo "<table border=1 style=table-layout:fixed;><tr>";
for ($i = 1; $i <= $limit; $i++) {
echo "<td valign=top><div class=getter id=post_$i><i>Result $i</i></div></td>";
if (($i%5 == 0)) {echo "</tr><tr>";}
}
echo "</tr></table>";
echo '</body></html>';
?>
...的JavaScript:
var master_off = false;
var getter_running_now = false;
function getter_outer(limit, i, longorshort){
if (getter_running_now) {alert ("Script is already running!"); return;}
getter_running_now = true;
if (master_off) {document.getElementById("main_info").innerHTML += "<br>master switch off, aborting!"; return;}
if (i >= limit) {document.getElementById("main_info").innerHTML += "<br>Got to the next getter when we shouldn't have, there's a bug!"; return;}
getter(limit, i, longorshort);
}
function getter(limit, i, longorshort){
if (master_off) {document.getElementById("main_info").innerHTML += "<br>master switch off, aborting!"; return;}
if (i >= limit) {document.getElementById("main_info").innerHTML += "<br>Got to the next getter when we shouldn't have, there's a bug!"; return;}
var post_number_element = "post_" + i;
var batch_result_script = "test_script_2a.php?longorshort=" + longorshort;
document.getElementById("iteration").innerHTML = "Iterations:<br>Doing iteration: " + i;
document.getElementById(post_number_element).innerHTML = "doing this one...<br>";
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4){
if (xmlhttp.status==200){
var result = "<b>result for " + post_number_element + " is:</b><br>" + xmlhttp.responseText + "<br><span style=color:green;>Success!</span>";
document.getElementById(post_number_element).innerHTML = result;
i++;
if (i >= limit) {
document.getElementById("main_info").innerHTML += "<br><span style=color:green;>Test complete!</span>";
}
else {getter(limit, i, longorshort);}
}
else {document.getElementById("message").innerHTML += "<br> - <span style=color:red;>http return status for iteration " + i + " was " + xmlhttp.status + "</span>";}
}
}
xmlhttp.open("GET",batch_result_script,true);
xmlhttp.send();
}
function master_switch(){
master_off = true;
document.getElementById("main_info").innerHTML += "<br><span style=color:red;>Master Switch Off!</span>";
}
...它通過AJAX調用腳本:
<?php
set_time_limit(600);
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
function generateRandomString($length = 10) {
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[mt_rand(0, $charactersLength - 1)];
}
return $randomString;
}
if (isset($_REQUEST["longorshort"]) && $_REQUEST["longorshort"] == "short") {$delay = mt_rand (5, 10);}
else {$delay = mt_rand (40, 55);}
sleep ($delay);
echo "<br>Here is a random string:<br>";
$length = mt_rand (5, 10);
echo generateRandomString($length);
?>
去這裏:http://www.scripttest1.cu.cc/test_script_2.php?longorshort=long在行動中看到它。與第一個腳本不同,它產生的錯誤是「空白迴應」。但我認爲這兩者是相關的。
這兩個腳本都可以在另一個共享服務器以及我有權訪問的LAMP的vps上正常工作。他們也在這臺服務器上工作了一段時間,然後才失敗。第一個測試腳本在死亡之前通常會經歷幾次迭代。第二個,與阿賈克斯,將有時運行直到完成,如果「longorshort」設置爲「短」。
此外,第一個測試腳本完美地從命令行運行。當然,第二個在那個環境下是行不通的。
服務器在Linux下運行PHP版本5.4.44和Apache版本2.4.16。
谷歌並不是我的朋友。我發佈到Stackoverflow,並得到了5(五)個意見,零響應。
這裏至少有人能給我一個線索嗎?或者失敗了,指向我替代Stackoverflow他們可能會真正回答我的問題?
使您的服務器回答HTTP 1.0,並使用類似於nokeepalive force-response-1.0降級-1.0的字符串。在HTTP1.1中引入了塊編碼。一個很大的方面說明,這是一個石膏來彌補腳本中的一個大錯誤,但我不是一個腳本專家,因此提供了石膏。 (與分塊編碼一樣,服務器以更「流」的方式發送數據以節省帶寬(帶有更少的頭部),並保存活動連接打開) – yagmoth555
哇,2天在Stackoverflow上沒有答案,20分鐘在這裏等等已經彈出。謝謝您的回答。我曾考慮過這樣做,但它有點燒燬村莊,以挽救它。我真的需要能夠在輸出生成時看到輸出,而長時間運行而沒有響應的腳本在我的經驗中往往會出現空白頁面。 –
然後做一個wireshark,它的流量很容易跟進。你會看到每個數據包將以http頭後面的數據塊的塊大小開始,並以0結束。 – yagmoth555