簡體   English   中英

停止請求服務器端

[英]Stopping requests server-side

我有一個名稱查找框,由您的典型 ajax 請求操作。 這是每次按下一個字母時觸發的 Javascript 的一般流程:

  • 如果 ajax 請求已經打開,則中止它。
  • 如果超時已經創建,則銷毀它。
  • 設置新的超時以在半秒內運行以下內容:
  • 通過ajax將字符串發送到'nameLookup.php'
  • 等待回應
  • 顯示結果

問題是 nameLookup.php 非常占用資源。 在某些情況下,多達 10,000 個名稱會從 SQL 數據庫中提取、解密並與字符串進行比較。 在正常情況下,請求可能需要 5 到 60 秒的時間才能返回。

我完全理解,當您在客戶端中止請求時,服務器仍在處理事情並將結果發回。 只有客戶端知道忽略響應。 但是服務器越來越忙於處理所有這些請求。

所以如果你這樣做:

  • 請求 1
  • 中止請求 1
  • 請求 2
  • 中止請求 2
  • 請求 3
  • 等待請求 3 的響應

服務器要么在完成 1 和 2 之前都沒有處理請求 3... 要么就是因為在處理請求 1 和 2 上太忙了,以至於請求 3 花費了很長時間。

我需要知道如何告訴服務器停止處理請求 1 和 2,以便我可以釋放資源來處理請求 3。

我在客戶端使用 Javascript 和 jQuery。 服務器端的 PHP/Apache 和 SQL。

  1. 將布爾值存儲在數據庫中的表或會話中。
  2. 讓您的資源密集型腳本定期檢查該值,看看它是否應該繼續。 如果 DB 說停止,那么您的腳本會自行取消(通過調用return;例如在當前函數中)。
  3. 當你想取消時,而不是調用abort(); ,發出 AJAX 請求以將該值設置為false
  4. 下次資源檢查該值時,它將看到它必須停止。

潛在限制: 1. 您的腳本無法定期檢查數據庫。 2. 根據腳本檢查數據庫的頻率,可能需要幾秒鍾才能有效地終止腳本。

我認為這個問題缺少一些東西。 執行請求的觸發器是什么? 您可能正在嘗試解決錯誤的問題。

讓我詳細說明一下。 如果您的查找框實際上正在執行某種自動完成,並且每次用戶按下一個鍵時都在進行新的搜索,那么您將遇到您所描述的問題。

這種情況下的解決方案不是殺死所有進程。 解決方案在於不啟動它們。 因此,您可能會做出一些決定,例如如果只有一個要搜索的字符,則不嘗試搜索 - 假設我們選擇三個。 然后我們可能會說我們想等到我們可以合理地確定用戶已經完成輸入,然后再發送請求。 假設我們等待 1 秒鍾。

現在,如果有人在您的姓名列表中查找所有 Paul 的名字,當他們輸入“pau”並暫停 1 秒時,會發送一次搜索,而不是依次搜索“p”、“pa”和“pau”……所以不需要殺任何東西。

我想出了一個很棒的解決方案,我已經測試過了,而且效果很好。 只需幾行 PHP 代碼即可放入資源密集型的任何文件。

此解決方案利用來自服務器的進程標識符 (PID) 我們可以使用兩個 PHP 函數: posix_getpid() 獲取當前 PID 和 posix_kill() 殺死另一個 PID。 這也假設您已經在其他地方調用了 session_start()。

這是代碼:

//if any existing PIDs to kill, go through each
if ($_SESSION['pid']) foreach ($_SESSION['pid'] as $i => $pid) {

    //if posix_kill returns true, unset this PID from the session so we don't waste time killing it again
    if(posix_kill($pid,0)) unset($_SESSION['pid'][$i]);

}

//now that all others are killed, we can store the current PID in the session
$_SESSION['pid'][]=posix_getpid();

//close the session now, otherwise the PID we just added won't actually be saved to the session until the process ends.
session_write_close();

需要注意的幾點:

posix_kill有兩個值。 第一個是pid,第二個應該是此列表中的信號常量之一。 對我來說沒有任何意義,其他人似乎只使用 0 就成功了,當我使用 0 時,它返回 true。 所以不管怎樣!

在資源密集型事情開始發生之前調用session_write_close()至關重要。 否則,在頁面的所有處理完成之前,已保存到會話中的新 PID 不會實際保存到會話中。 這意味着下一個流程不會知道取消仍在繼續並永遠持續的流程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM