2012-04-10 26 views
6


Tôi có một ứng dụng PHP nhận được nhiều cuộc gọi ajax.
Tôi nhận thấy rằng, khi hai hoặc nhiều cuộc gọi xảy ra cùng một lúc thì chúng không được thực hiện đồng thời, lệnh đầu tiên phải dừng lại để lệnh thứ hai thực hiện.
Tôi đã xây dựng một thử nghiệm nhỏ để thử khắc phục sự cố này. Tôi có một html như thế này:Kết nối đồng thời với Apache đến từ cùng một máy khách

<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> 

Các test.php chứa:.

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

Vì vậy, sau khi thực hiện $ ('nút') bấm() trên công cụ phát triển (hoặc firebug) an ủi yêu cầu xảy ra cùng một lúc nhưng trả lại các câu trả lời 2 giây sau lần cuối cùng, thay vì cả bốn câu trả lời cùng một lúc (2 giây sau).
Vâng, tôi đã thử mở trong các trình duyệt khác, đồng thời, tệp này và nó hoạt động, nó đã được thực thi đồng thời. Ý tôi là, chạy trên chrome và trong firefox mở trang trong tab hiển thị 'Test' trong 2 giây trong khi phản hồi từ yêu cầu chrome ajax đến 2 giây sau khi yêu cầu cuối cùng kết thúc, do đó yêu cầu trình duyệt khác không có hiệu lực vào lần đầu tiên một cuộc gọi (đó sẽ chứng minh đây là một vấn đề phiên, nhưng xem bên dưới).
Điều tương tự cũng xảy ra nếu tôi mở nhiều tab cho test.php.

Tôi đã thử thay đổi phiên thành memcache - Mọi người nói, trong các câu hỏi khác, rằng phiên có thể bị khóa. Nó làm cho rất nhiều ý nghĩa nhưng ngay cả sau khi thay đổi từ tập tin để memcache vấn đề vẫn tồn tại (và kịch bản không có phiên, và session_autostart là tắt)

Tôi thực sự điều về một vấn đề cấu hình với apache, kể từ lần đầu tiên sau một thời gian, nếu tôi thực thi kịch bản nó sẽ thực hiện tất cả 4 cuộc gọi ajax đồng thời! Tôi đang suy nghĩ về một số bảo vệ DoS hoặc một cái gì đó như thế này.

Dù sao, mọi trợ giúp sẽ được đánh giá cao!


Ok, đã giải quyết được sự cố.

Đó là vấn đề về khóa phiên sau khi tất cả, vấn đề là memcached khóa phiên quá!
Phải cài đặt php_memcached 2.0.1 có cờ khóa trong memcached.ini và sử dụng phiên bản đó. Đã giải quyết vấn đề.

Mặc dù khi có yêu cầu cho cùng một url (trong ví dụ trên tôi đã sử dụng test.php 4 lần), nó vẫn thực thi từng lần một. Tôi khá chắc chắn đó là hành vi đúng vì nó không có ý nghĩa nhiều để yêu cầu một nguồn tài nguyên nhiều lần cùng một lúc. Thay đổi ví dụ của tôi để yêu cầu test1.php, test2.php và như vậy và nó hoạt động tốt. Cũng hoạt động nếu chuỗi truy vấn bị thay đổi.

Cảm ơn sự giúp đỡ của bạn!

PS: Không có danh tiếng để trả lời câu hỏi của riêng tôi quá sớm vì vậy đây là câu trả lời

+2

thử thêm số ngẫu nhiên làm chuỗi truy vấn vào yêu cầu của bạn để đảm bảo rằng đó không phải là vấn đề về bộ nhớ đệm, như '$ .get (" test.php? "+ Date.now());' – lunixbochs

+0

Bạn muốn thực hiện tất cả các yêu cầu cùng một lúc? Hay bạn muốn tránh điều này? – kuba

+0

Tôi muốn làm tất cả cùng một lúc. Tôi nhận thấy không đúng khi kiểm tra cùng một url. Sau đó tôi thử nghiệm test1.php mặc dù test4.php. Vấn đề vẫn tồn tại nhưng tôi đã tìm thấy nguyên nhân gây ra nó, tôi sẽ trả lời bằng giải pháp. – filaruina

Trả lời

-2

yêu cầu HTTP là độc lập với nhau - theo định nghĩa giao thức HTTP là quốc tịch. Mỗi $.get() bạn thực hiện là một yêu cầu http hoàn toàn riêng biệt và MỚI, vì vậy bạn kết thúc với 4 yêu cầu HTTP, 4 cuộc gọi sleep() riêng biệt và 4 kết quả đầu ra riêng biệt từ máy chủ.

+0

Câu trả lời của bạn không thể tách rời chủ đề. – frostymarvelous

6

trong trường hợp của tôi các chức năng:

session_write_close();

giải quyết vấn đề của tôi

tôi có chương trình tiếp theo, một trang chính mà gọi định kỳ một file ajax gọi ajax.php. Nó được gọi là mỗi giây "n".

Và, biểu mẫu của tôi có nút trả lại báo cáo được gọi là ajax (** reporte.php **) Chỉ được gọi theo yêu cầu của người dùng (nhấp) và có thể mất một phút để tạo kết quả.

Hầu hết thời gian, ajax.php mất 20ms để chạy nhưng, nếu report.php đang chạy ajax.php bị đóng băng cho đến khi reporte.php kết thúc tác vụ. Và tồi tệ nhất, ajax.php có thể được xếp chồng lên nhau.

reporte.php (trước)

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

reporte.php (sau khi sửa chữa)

<?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). 
?> 

Trước khi các giải pháp (ảnh chụp màn hình của plugin firebug của Firefox): before

Sau giải pháp after

Kiểm tra xem trước khi giải pháp, reporte.php và ajax.php đều đang tải (và ajax đã được xếp chồng lên nhau trong một số cuộc gọi). Và sau khi giải pháp, reporte.php đang tải trong khi mọi cuộc gọi ajax liên tiếp đã được tải.

Lưu ý rằng sau hàm session_write_close(), không thể (hoặc được khuyến nghị) sử dụng bất kỳ hàm và giá trị phiên nào.

+0

Giải quyết được sự cố của tôi. Nhận thấy yêu cầu ít chuyên sâu đã trở lại một giây sau đó. Profiled, thử nghiệm, mã máy chủ là tốt. Sau đó nhận thấy đó là yêu cầu đồng thời. Phiên đã đóng cố định – frostymarvelous

Các vấn đề liên quan