2014-03-24 70 views
1

我們當前的部署過程是這樣的:導致CDN緩存舊的或損壞的文件部署的競爭條件

  1. 使用grunt創造生產資產。
  2. 創建我們的CDN一個郵戳,並指向文件(例如/scripts/20140324142354/app.min.js)。

    旁註:我聽說過這個過程叫做「版本控制」,但我不確定它是否是合適的術語。

  3. 將構建提交給github。在Web服務器上

  4. 運行git pull檢索從GitHub的新代碼。

這是一個node.js網站,我們正在使用forever -w來監視文件更改並相應地更新網站。

我們有一個路線設置在我們的應用程序通過/scripts/*/app.min.js服務於最新版本的應用程序。

我們這樣版本的原因是因爲我們的CDN被設置爲無限期地緩存JavaScript文件,這故意創建緩存未命中,以便在CDN(以及我們用戶的瀏覽器中)更新代碼。

這工作正常大多數的時間。但是,如果其中一臺服務器在檢查新代碼時稍微有些滯後,那麼它會崩潰。

有時一個客戶端點擊網頁而部署正在進行中,並試圖找回從CDN新的JavaScript代碼。 CDN嘗試檢索它,但點擊未完成檢查新代碼的服務器並緩存舊的或部分下載的文件,從而導致各種問題。

由於我們的CDN有許多邊緣位置,所以這個問題更加嚴重,所以我們的辦公室並不總是立即顯示問題。某些邊緣位置可能拉下了舊/壞的代碼,而其他邊緣位置可能拉下了新的/好的代碼。

有沒有更好的辦法做到這些部署將避免這個問題?

回答

2

第4步應該是:

git archive --remote $yourgithubrepo --prefix=$timestamp/ | tar -xf - 
stop-server 
ln -sf $timestamp current 
start-server 

您的服務器將在任何時候都使用current目錄(當然,一個符號鏈接)。無論部署需要多長時間,您的應用程序都處於一致狀態。

0

我會繼續和發佈,我們現在正在使用我們的遠從理想猴子補丁。

我們部署了一次,可能會或可能不會按計劃進行,一旦我們確定代碼部署在所有服務器上,我們會進行另一次構建,其中唯一發生變化的是版本號。

然後我們再按服務器部署服務器。

競爭條件依然存在,但由於兩個版本之間的應用程序代碼相同,所以這掩蓋了這個問題,因爲無論CDN點擊哪個服務器都會得到「最新」代碼。

3

作爲一個一般的經驗法則:

不要做現場升級。(除非語言支持,但即使是這樣認爲的兩倍)

使用git pull,然後等待應用程序的通知文件的更改拉動代碼聽起來很像上世紀90年代:上傳PHP文件要使用FTP的Apache Web服務器(或者如果你很酷的話可以用sftp)並且等待apache注意到它們已經被更新了。它不可能原子地發生,所以當然是有一個競爭條件。一些用戶得到一半建立和破碎的網站。

我建議只在沒有人使用它時升級您的實時和正在運行的應用程序。希望你在某種類型的負載均衡器後面有一個服務器池,這將允許你一次刪除它們並升級它們。

這將意味着用戶將能夠在同一時間取決於他們如何及何時訪問它同時使用舊的和新的網站,但是這是更好的那麼不能夠在所有訪問它。

理想情況下,您將能夠使用新版本的站點啓動運行的每個Web服務器的副本。檢查新版本是否正常工作,然後自動更新負載平衡器,以便每個人都能同時碰到新的站點。只有一切都經過驗證才能完美運行,舊機器將關閉並退役或重新使用。在你的程序中

+0

儘管可以做到這一點(我們使用EC2),那麼這樣的部署需要多長時間?當我們每天進行多個部署時,部署需要幾分鐘的時間似乎不可行。 –

+1

您花費多少時間將一切事物每天兩次升級兩次?如果您擔心必須坐在每臺機器上觀看升級,只需將其自動化,以便您可以處理其他事情。 – Daniel