2010-05-14 57 views
8

我有一個運行相當多的數據庫查詢的PHP網站。通過某些參數組合,這些查詢最終可能會運行很長時間,從而觸發一個醜陋的超時消息。我想根據我的站點樣式的其餘部分用主題很好的超時消息替換它。如何讓PHP腳本在等待長時間運行的MySQL查詢時正常超時?

預見通常回答這樣一個問題:

  1. 「優化你的查詢,使他們不這麼長時間運行」 - 我記錄長時間運行的查詢和優化他們,但只有我在用戶受到影響後瞭解這些信息。

  2. 「增加您的PHP超時設置(例如,set_time_limit,max_execution_time),以便長時間運行的查詢可以完成」 - 有時查詢可以運行幾分鐘。我想告訴用戶在這之前有問題(例如30秒後)。

  3. 「使用register_tick_function監視腳本運行了多長時間」 - 這僅在腳本中的代碼行之間執行。當腳本正在等待數據庫的響應時,tick函數不會被調用。

萬一有幫助,該網站是使用Drupal的(有很多定製的)所建,是一個虛擬專用Linux服務器上使用MySQL 5上運行PHP 5.2

回答

0

connection handling文檔是什麼你需要。

基本上,您需要使用register_shutdown_function()註冊關閉功能。無論腳本是否成功完成,用戶已取消(ESC鍵)還是超時,腳本完成後都會調用此函數。

該關閉功能可以調用connection_status()功能。如果connection_status()返回2(TIMEOUT)並且上一頁是運行棘手查詢的頁面,則可以將用戶重定向到一個頁面,說「對不起,但我們現在正在經歷高服務器負載。」或其他。

+0

這隻涉及到運行php代碼的地方(通常是一個web服務器)和瀏覽器之間的連接 - 而不是web服務器和DBMS – symcbean 2010-05-14 12:00:41

+0

他沒有要求與DBMS通信的東西,只是一種處理腳本超時的機制優雅地說,這就是connection_status()的設計目的。我編輯了我的答案以提供更多信息。 – Mathew 2010-05-14 16:16:19

+0

這聽起來像我需要的解決方案,但我正在努力與重定向。我正在嘗試使用PHP header()函數,但它表示標題已經發送。即使有一個簡單的測試用例: 'set_time_limit(1); register_shutdown_function( 'clean_shutdown');' 而(真){ } 功能clean_shutdown(){ 如果(CONNECTION_STATUS()&CONNECTION_TIMEOUT){ ob_end_clean(); header('Location:http://www.bbc.co.uk',TRUE,500); } } 我仍然收到一個「頭文件已經發送(在第5行)」的消息,但是我看不到它們會被髮送到哪裏。 – 2010-05-17 09:43:33

3

沒有異步的mysql調用,也沒有分叉輕量級線程的範圍。

儘管可以將PHP代碼拆分爲兩層,並使用可以異步調用的連接,但這種方法的問題在於數據庫層在上層服務器放棄之後仍嘗試運行查詢獲得結果 - 可能會阻止其他用戶的DBMS。 (你更有可能更頻繁地請求頁面超時)。

如果將超時處理推入位於Web服務器前的反向代理,則會出現同樣的問題。

實現超時最明智的地方是數據庫本身 - 但AFAIK,MySQL不支持。

因此,下一個選項是在PHP和數據庫之間建立一個代理 - 這可以是自包含的 - 爲每個請求生成2個輕量級線程(1運行查詢,第二個作爲監視器殺死第一個太長) - 但這不僅需要以支持輕量級線程的語言編寫代碼,還需要定義與PHP通信的協議。

但是採取不同的方法來處理代理模型 - 您可以使用proc_open產生一個單獨的PHP進程,並將stdout流設置爲非阻塞 - 這樣PHP可以繼續運行並檢查代理是否有運行查詢。如果它超時,那麼作爲代理的父代,它可以發信號通知它關閉(proc_terminate()),這應該停止查詢在數據庫上運行。

當然,這將意味着很多開發工作。

設置一個或多個從屬DBMS來運行您的慢速查詢可能會證明更簡單 - 可能會帶來智能負載平衡。或者查看其他方式讓慢速查詢變得更快 - 就像預合併一樣。

HTH

C.

0

是您的服務器調整與APC,內存緩存,加速和Drupal緩存?那些替代路線工作得很好。

否則,在Drupal中會運行什麼類型的腳本會導致這種情況?出於好奇,你正在運行視圖和麪板?

+0

這不是一個Drupal問題。我們正在使用視圖和麪板,但不在網站的這一部分。 (我知道這些模塊仍然會被加載,但我們沒有給它們打電話)。這裏的問題僅限於數據庫訪問,而這是導致問題的客戶特定查詢。有些客戶比其他客戶擁有更多的數據,有些客戶要求比其他客戶更長的時間。我已經創建了彙總表來加快許多查詢,但仍有工作要做。我正在尋找一些能夠在工作正在進行時提供更清晰的用戶體驗的產品。 – 2010-05-17 07:29:51