2012-07-18 33 views
4

我們使用多個服務器處理以循環方式進行負載平衡的傳入Web請求。我遇到了一個我不確定如何解決的問題。分片服務器配置中的PHP文件上傳

使用AJAX(qqFileUploader),我正在上傳文件。默認情況下它會進入/tmp文件夾,這很好。問題是,當我嘗試檢索該文件時,該檢索請求被下一臺服務器處理,其中沒有有我上傳的文件。如果我一再重複請求,它將最終到達存儲文件的原始服務器(通過輪循負載均衡),然後我可以打開它。顯然這不是一個好的解決方案。代碼:http://jsfiddle.net/Ap27Z/。爲了簡潔,我刪除了一些內容。您會看到上傳器對象調用PHP文件進行文件上傳,然後在文件上傳完成後,另一個AJAX調用將處理該.csv文件的腳本。這是循環過程中迷失的地方。

我在這裏讀了幾個關於上傳文件到內存的問題,看起來它基本上不是現在可行的。是否有另一個選項可用於上傳文件並在同一請求中處理所有文件?

+0

爲什麼網頁必須告訴服務器來處理它?你可以將文件變成數據庫中的BLOB嗎? – Pete 2012-07-18 14:25:43

+1

您需要能夠使用絕對名稱引用每個服務器(即每個服務器都有自己的A記錄),並且您需要在響應中返回單個服務器的名稱,以便將文件上載到POST請求客戶端 - 例如用cookie - 這樣客戶端可以在嘗試檢索文件時用絕對名稱引用正確的服務器。 – DaveRandom 2012-07-18 14:25:44

+0

出於興趣,這是一個DNS循環或反向代理? – DaveRandom 2012-07-18 14:28:21

回答

6

這種類型的問題的經典解決方案是在負載均衡器上使用粘性會話。這可能不是一個好的解決方案,因爲它會修改整個設置來解決一個小問題。

我會建議爲每臺機器添加一個子域前綴,例如上傳到www.example.com,然後爲每臺服務器分配一個額外的子域www1.example.com,www2.example.com,它們總是直接傳遞到該服務器,而不是循環DNS。

作爲成功結果的一部分,您可以傳回指向確切服務器的服務器名稱,而不是負載平衡名稱,然後所有引用上載數據的後續Ajax調用都使用該服務器特定的域名,而不是通用的負載平衡域名。

是否有另一個選項可用於上傳文件並在同一個請求中處理所有文件 ?

當然,爲什麼不呢?處理數據POST的代碼可以做你想做的任何事情。

+0

LOL的很好的解釋,有時候簡單的事情是被忽視的東西。我沒有考慮只處理上傳文件的代碼中的文件處理。 – 2012-07-18 14:31:46

2

有(至少)2個解決你的問題:

  1. 更改負載平衡

有幾個負載均衡代理支持會話親和力a.k.a.「粘性會話」。這意味着用戶總是在會話中獲得同一臺服務器。

兩個方案可以以這種方式行事是HAProxyrelated question here on SO)和nginxa custon moduletutorial here)。

  1. 您有機會獲得文件的位置

另一個選擇是改變您存儲文件的位置,所有服務器都可以通過同一位置訪問某些地方。例如,這可以是NFS掛載或數據庫(將文件存儲爲BLOBS)。這樣,哪個服務器處理請求並不重要,因爲它們都可以訪問該文件。

+0

我沒有選擇更改負載平衡的選項,但是像存儲臨時文件的靜態位置的想法一樣。 – 2012-07-18 14:32:53

+0

但是不要通過NFS掛載'/ tmp'。其他進程可能使用該文件夾(例如,默認配置中的PHP會話),並通過NFS發送所有內容可能會減慢一切。而是,爲您上傳的文件使用單獨的文件夾。 – Carsten 2012-07-18 14:35:54