NO IMAGE

如果沒有任何經驗,學習如何擴充套件一個網站是相當困難的。假設現在你有很多像highscalability.com那樣網站,你需要一些好的解決方案來擴充套件它們,但是世上沒有“萬能藥”,沒有哪個解決方案可以適應所有網站的需要。你不得不自己動手,通過不斷地思考來找到一個能滿足你的需求的解決方案。我也是這樣做的。

幾年以前,我的老闆來找我,然後對我說:“我們有一個新專案想交給你來做。主要是一個網站的重構,在一個月內,這個站點已經擁有100萬個使用者了。你必須重新構建這個網站,來確保我們可以應對將來逐漸增加的使用者數量。”我已經是一個有經驗的程式設計師了,但是在這些方面並不擅長,所以我不得不開始學習如何擴充套件一個網站——整個過程歷盡了艱難困苦。(相關文章推薦:重構:“為什麼”和“怎麼做”)

這個網站的後臺軟體是一個PHP內容管理系統,基於Smarty和MySQL。第一個任務是找到一個合適的託管公司,這個公司需要具有豐富的經驗,可以為我們管理伺服器。經過一番調查研究,我們找到了一家這樣的公司,然後告訴他們我們的需求,他們給我們推薦的配置如下:

  • 負載均衡器 ( Fallback)
  • 2個Web伺服器
  • MySQL伺服器( Fallback)
  • 開發機器

他們說,這就是我們需要的所有東西了——對此,我們深信不疑。我們最後得到的配置是:

  • 負載均衡器 (單核, 1GB 記憶體, Pound)
  • 2個Web伺服器 (雙核, 4GB 記憶體, Apache)
  • MySQL伺服器 (四核, 8GB 記憶體)
  • 開發機器 (單核, 1GB 記憶體)

這個配置十分的基礎,並沒有做進一步優化。為了同步檔案(PHP和媒體檔案),他們建立了一個active-active DRBD。最後,重構開始了——當然,我們很興奮。一大早,我們把域名切換到了新的IP上,執行我們的監控指令碼,然後盯著螢幕看。我們馬上在這些機器上看到了流量,一切似乎都工作的很好。頁面載入的很快,MySQL負擔了大量的查詢任務,我們所有人都很高興。

然後,突然我們的電話開始響個不停:“我們不能訪問你們的網站了,這是怎麼回事?”我們看了一下我們的監控軟體,事實的確如此——伺服器都被frozen了,站點處於離線狀態!當然,我們做的第一件事情是打電話給我們的託管服務提供商:“我們的所有伺服器都宕機了。這是怎麼回事?”他們答應檢查一下機器,一會再打過來。這個電話來了:“你的系統根本就無法插手。你做了什麼?它完全被搞砸了。”他們停止了負載均衡器,然後讓我觀察一下其中一個Web伺服器。看到那個index.php檔案,我大吃一驚。它包含一些奇怪的C程式碼片段,錯誤訊息和一些看起來像日誌檔案的東西。經過進一步的調查,我們發現是DRBD引發了這次事故。

“殺死”你的伺服器的方法之一

把Smarty compile和模板快取放到一個高負載的active-active DRBD叢集上,那麼你的伺服器將會掛掉!當我們的託管服務提供商修復了Web伺服器的時候,為了在這些伺服器的本地檔案系統上儲存Smarty快取檔案,我重寫了部分CMS程式碼。我們再次上線了!

現在是午後。這個網站通常在下午的晚些時候到傍晚達到峰值。晚上,幾乎沒有什麼流量。我們一直盯著監控軟體,我們所有人都緊張得不得了。這個網站可以被載入,但是後來,系統負載越高,響應就越慢。我增加了Smarty模板快取的生存期,希望這能產生效果——但是很可惜,這並沒有產生效果!不久,伺服器開始給出超時提示,空白頁面和錯誤資訊。有兩臺機器不能處理負載。

我們的客戶這個時候有一點緊張,但是他說:OK,重構通常會引發一些問題的。只要你能很快地修復它,那就沒事了!

我們需要一個計劃來減少負載,然後,我們和我們的託管服務提供商討論了這個問題。他們的一個系統管理員提出了一個好主意:“夥計,你的伺服器現在執行在一個非常常見的Apache mod_php架構上。把你的Web伺服器換成Lighttpd怎麼樣?它是一個相當小專案,但是維基百科都在使用它。”我們同意了。(相關文章推薦:更好的選擇 細數Apache伺服器的四個替代者)

“殺死”你的伺服器的方法之二

把一個開箱即用的Web伺服器架設在你的機器上,並且一點也沒有對它進行優化,那麼你的伺服器將會掛掉!那個管理員盡了他的最大努力,儘快地重新配置了所有的Web伺服器。他拋棄了Apache,然後切換到Lighttpd FastCGI Xcache上來。後來,當我們重新上線的時候,我們幾乎沒有再感受到壓力。這次,這些伺服器會維持多長時間呢?

這些伺服器執行的出奇地好。負載比以前低很多,平均響應時間也不錯。我們徹底放心了,然後我們都回家睡覺了。天已經很晚了,我們認為沒有其他的事情需要我們做了。第二天,網站執行的相當好,但是在高峰時段,它一直接近於崩潰的邊緣。我們發現MySQL是瓶頸,我們再次打電話給我們的託管服務提供商。他們建議在每個Web伺服器上用MySQL從伺服器進行MySQL的主-從同步。

“殺死”你的伺服器的方法之三

再強大的資料庫伺服器也有它的極限,當你到達它的極限的時候,你的伺服器將會掛掉!在這種情況下,某些時候你的資料庫會變得十分緩慢,以至於佇列中大量的網路連線會再次“殺死”我們的Web伺服器。不幸的是這個問題很難修復。內容管理系統在這方面十分的簡單,它本身並不支援單獨地讀取和寫入SQL查詢。重寫這一切花了很長時間,但是相對於每分鐘都遭遇到掛起休眠來說,是相當值得的。

MySQL同步真的成功了,網站最終穩定了!在接下來的幾周,幾個月裡,網站取得了成功,使用者的數量開始不斷地增加。流量再次超過我們的資源限制,這只是時間的問題。

“殺死”你的伺服器的方法之四

不提前作規劃,你的伺服器可能會掛掉!

幸運的是,我們一直在思考,並且一直在做規劃。我們優化了程式碼,減少了每個頁面載入的時候需要的SQL查詢的數量,我們意外地發現了MemCached這個好東東。首先,我們在一些核心功能上新增了對MemCached的支援,在一些重量級(執行緩慢)的功能上我們也新增了對MemCached的支援。當我們把這些變更部署以後,我們簡直不能相信這個結果——這感覺有點像發現了“聖盃”。我們每秒查詢的數量至少降低了50%。我們決定更多地使用MemCached,而不是購買另外一個Web伺服器。

“殺死”你的伺服器的方法之五

忘記做快取,你會浪費很多錢,而且,你的伺服器還會掛掉!事實證明,MemCached幫助我們減少了70%-80%的MySQL伺服器上負載,同時,在Web伺服器上,也產生了巨大的效能提升。頁面載入的相當快。

最終,我們的配置看起來似乎是完美的。即使在高峰時段,我們也無須再擔心崩潰或頁面響應緩慢了。我們搞定它了嗎?不!一臺藍色的Web伺服器開始有一點響應緩慢了。然後出現了一些錯誤訊息,空白頁面等等。這個系統負載能力很不錯,在大多數情況下伺服器也都在工作,但是只是在“大多數情況下”而已。

“殺死”你的伺服器的方法之六

把成百上千個小檔案放在一個資料夾裡,當索引節點耗盡的時候,你的伺服器將會掛掉!

是的,你沒有看錯。我們過去只是關注MySQL,PHP和Web伺服器本身,並沒有太關注檔案系統。Smarty快取檔案儲存在本地檔案系統裡——所有的快取檔案都儲存在同一個目錄下。解決方案是把Smarty放在一個專用的ReiserFS分割槽裡。另外,我們還開啟了Smarty的“use_subdirs”選項。

在過去的幾年裡,我們一直在優化頁面。我們把Smarty快取放到了memcached中。為了更快速地處理靜態檔案,我們安裝了Varnish來減少I/O負載。我們還切換到了Nginx(Lighttpd會隨機的產生error 500的訊息),安裝了更多的記憶體,購買了更好的硬體,更多的硬體……這個列表永遠不會結束。

總結

擴充套件一個網站是一個永遠不會結束的過程。當你解決了一個瓶頸以後,很可能馬上會遇到下一個瓶頸。永遠都不要這樣想:“就是這樣,我們大功告成了”然後就靠邊站了。這會“殺死”你的伺服器,甚至是你的業務。規劃和學習是一個持續的過程。如果你因為缺乏經驗或資源而不能自己完成這個工作,那麼可以找一個有能力勝任這個工作,而且很可靠的合作伙伴,和它一起來做這個工作。永遠都不要停止和你的團隊和合作伙伴溝通當前遇到的一些問題和即將會遇到的一些問題。思考在前才能爭取主動。