2012-04-10 113 views
6


我有一個接收大量Ajax調用的PHP應用程序。
我注意到,當兩個或更多的調用同時發生時,它們不會同時執行,第一個必須停止,所以第二個執行。
我已經構建了一個小測試來嘗試解決這個問題。我有一個這樣的HTML:來自同一客戶端的Apache的併發連接

<html> 
<head> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
</head> 
<body> 
    <a href="test.php">Test</a> 
    <button>Click</button> 
    <button>Click</button> 
    <button>Click</button> 
    <button>Click</button> 
    <script type="text/javascript"> 
     $('button').click(function() { 
      $.get("test.php"); 
     }); 
    </script> 
</body> 
</html> 

的test.php的包含:

<?php 
sleep(2); 
echo 'Test'; 
?> 

因此,執行$( '按鈕')後點擊()上的開發工具(或螢火蟲)安慰請求同時發生,但在最後一個請求後2秒返回答案,而不是同時返回(2秒後)。
那麼,我試圖在其他瀏覽器打開,同時,這個文件,它的工作,它併發執行。我的意思是,在chrome和firefox上運行這個操作,打開頁面中的標籤顯示2秒內的「測試」,而來自chrome ajax請求的響應在最後一次請求結束後2秒內顯示,所以其他瀏覽器請求對第一個請求沒有影響一個電話(這將證明這是一個會話問題,但見下文)。
如果我打開test.php的多個選項卡,也會發生同樣的情況。

我試過將會話更改爲memcache - 人們在其他問題中表示會話可能被鎖定。它很有道理,但即使在從文件更改爲memcache之後,問題仍然存在(並且腳本沒有會話,並且session_autostart關閉)

我真的關於apache的配置問題,因爲在第一次過了一段時間,如果我執行腳本,它將同時執行所有4個Ajax調用!我正在考慮一些DoS保護或類似的東西。

無論如何,任何幫助將不勝感激!


好的,解決了這個問題。

畢竟這是一個會話鎖問題,問題是memcached也鎖會話!
不得不安裝php_memcached 2.0.1,它在memcached.ini中有一個鎖標誌並使用該版本。解決了這個問題。

雖然當一個請求是針對相同的url(在上面的例子中我使用了test.php 4次),它仍然一次執行一個。我很確定這是正確的行爲,因爲同時多次請求資源沒有多大意義。更改我的示例以請求test1.php,test2.php等等,它工作得很好。查詢字符串更改也適用。

感謝您的幫助!

PS:不要有信譽回答我的問題這麼早所以這裏就是答案

+2

嘗試追加一個隨機數作爲查詢字符串到您的請求,以確保它不是緩存問題,如'$ .get(「test.php?」+ Date.now());' – lunixbochs 2012-04-10 18:35:10

+0

您想使所有的請求同時?或者你想避免這種情況? – kuba 2012-04-10 18:38:19

+0

我想同時做所有事情。我注意到測試相同的URL是錯誤的。然後我通過test4.php測試了test1.php。問題依然存在,但我發現是什麼原因造成的,我會用解決方案回答。 – filaruina 2012-04-10 20:38:36

回答

-2

HTTP請求是相互獨立的 - 通過定義HTTP協議是無狀態的。您執行的每個$.get()都是一個完全獨立的新HTTP請求,因此您最終會收到4個HTTP請求,4個獨立的sleep()調用以及來自服務器的4個獨立輸出。

+0

你的答案不能脫離主題。 – frostymarvelous 2013-11-05 02:23:40

6

在我的情況的功能:

session_write_close();

解決我的問題

我有一個程序,調用一個反覆AJAX文件名爲ajax.php一個主頁。它被稱爲每「n」秒。

而且,我的表單有一個返回一個報告的按鈕,它通過ajax調用(** reporte.php **)它僅被用戶的請求調用(單擊),可能需要一分鐘才能生成結果。

大部分時間,ajax.php需要20ms才能運行,但是,如果report.php正在運行,則ajax.php會凍結,直到reporte.php完成任務。而最糟糕的是,ajax.php可以堆疊。

reporte.php(前)

<?php 
// Some PHP Code goes here. 
// The rest of the PHP code (mostly, the slow part of the process). 
?> 

reporte.php(修訂後)

<?php 
// Some PHP Code goes here. (ideal if it is the fast part). 
session_write_close(); // fix for concurrent ajax 
// The rest of the PHP code (mostly, the slow part of the process). 
?> 

解決方案(Firefox的螢火插件的截圖)之前: before

解決方案後 after

檢查解決方案之前,reporte.php和ajax.php是否仍在加載(並且ajax已被多次調用)。以及如何在解決方案後,reporte.php正在加載,而每個連續的ajax調用已經加載。

請注意,在session_write_close()函數之後,不可能(或不推薦)使用任何會話函數和值。

+0

解決了我的問題。注意到不太密集的請求稍後返回。配置文件,測試過的服務器代碼很好。然後注意到它是同時請求。會議閉幕修復它 – frostymarvelous 2013-11-05 02:22:57