2011-04-03 49 views
3

好了,在我的頭上,這是有點複雜,我希望我可以解釋它。如果有什麼不清楚的地方,請發表評論,以便我可以改進這個問題。php應用程序中的關鍵代碼部分?

我想要處理用戶文件上傳到服務器3。

因此,我們必須

  • 用戶
  • 的網站(服務器在網站上運行)
  • 存儲服務器(臨危文件)

的流量應如:

  1. 網站要求上傳的URL從雲存儲網關,直接指向最終的存儲服務器(類似http://serverXY.mystorage.com/upload.php)。除了請求之外,還會發送「目標路徑」(網站特定和全局唯一)以及重定向網址。

  2. 網站生成上傳形式與存儲服務器上載URL作爲目標時,用戶選擇文件並點擊提交按鈕。存儲服務器處理請求後,將文件保存到臨時位置(這是'/tmp-directory/'.sha1(target-path-fromabove))和重定向回到那個已經由網站指定的重定向URL。 「目標路徑」也通過了。

  3. 如果用戶取消進程或連接被中斷或者其他什麼東西,我不希望任何「幻影文件」留下來!此外,還必須避免在網站數據庫中尚未正確處理存儲雲中的條目然後破壞的條目。多數民衆贊成這樣做的原因和下一步

  4. 這些都是關鍵步驟

    • 現在的網站寫EN進入自己的數據庫,並將其發給存儲API一個寧靜的請求(簽署,網站有
    • 副本從存儲服務器到最終位置上的臨時位置的文件(這應該是快的,因爲它僅重命名)
    • 同其餘的要求也插入數據庫行與祕密令牌認證)存儲網絡數據庫以及網絡站點ID作爲所有者
  5. 存儲服務器上tmp目錄中超過24小時的所有文件都會自動刪除。

如果用戶關閉瀏覽器窗口或連接中斷,服務器上的程序流程也會中止,對吧? 只執行析構函數和註冊的關閉函數,是否正確?

我能以某種方式使這部分代碼「關鍵」,以使服務器,如果它一旦進入這個代碼的一部分,它執行到年底德無論用戶是否中止網頁加載與否?

(當然我知道,服務器崩潰或錯誤可以隨時中斷,但我的擔心是對正規流程現在)

一個我的是有一個標誌,並在一個時間戳網站數據庫將文件標記爲「已完成」,並檢查舊的未完成文件的cronjob,並將其從存儲雲中刪除,然後從網站數據庫中刪除,但我真的很想避免這些額外的字段和過程。

我希望存儲API是非常通用的,並將其用於許多其他未來的項目中。

我看了一下Google存儲的開發人員和Amazon s3。

他們有同樣的問題,甚至更糟。在亞馬遜S3中,您可以「簽署」您的發佈請求。因此,用戶根據您的權限上傳文件並直接保存並存儲,您必須付費。 如果連接中斷,用戶永遠不會回到你的網站,你甚至不知道。 因此,您必須存儲您簽名的所有上傳URL並在cronjob中檢查它們,並刪除沒有「到達目的地」的所有內容。

該問題的任何想法或最佳實踐?

回答

1

如果我正確閱讀此內容,那麼您將在存儲服務將用戶重定向到您的網站時調用的腳本中執行關鍵操作。

我看到了確保關鍵步驟均以其全部進行兩種選擇:

  1. 確保PHP無視連接狀態,並通過使用ignore_user_abort()運行腳本完成。
  2. 觸發一些與面向用戶的腳本分開執行關鍵操作的後端進程。如果您正在使用* NIX服務器(man at瞭解更多詳細信息)或像專用隊列管理守護程序那樣複雜,就像將LrdCasimir建議一樣,這可能就像將任務放入at隊列一樣簡單。

我遇到過的這類問題都有相當耗時的流程,所以我一直使用Option 2來提供對瀏覽器的響應,並釋放網絡服務器。選項1很容易實現,但選項2最終更容錯,因爲更新將保留在隊列中,直到它們可以成功傳送到存儲服務器。

PHP手冊中的connection handling頁面提供了很多關於HTTP連接期間發生的事情的很好的見解。

0

我不確定我會稱之爲「最佳實踐」,但對於這類問題的一般方法有一些想法。當然,允許REST請求事務異步發生,可以通過監聽進程請求的守護進程來進行(通過監視文件的變化,或者套接字,共享內存,數據庫,無論你在您的環境中認爲最適合IPC),或者是運行頻繁的cron作業,它可以提取和傳輸文件。這樣做的好處是,您可以向上傳文件的用戶發送一條快速消息,而後臺進程可以嘗試,如果與REST服務存在連接問題,請重試。甚至可以進行一些AJAX輪詢,以便用戶在完成REST過程時可以顯示一個很好的JS消息。