如何構建可伸縮的Web應用?
- 2019 年 12 月 31 日
- 筆記
為什麼要構建可伸縮的Web應用?
想像一下,你的營銷活動吸引了很多用戶,在某個時候,應用必須同時為成千上萬的用戶提供服務,這麼大的並發量,服務器的負載會很大,如果設計不當,系統將無法處理。
接下來發生的就是,隨機錯誤、緩慢的內容加載、無休止的等待、連接斷開、服務不可用等問題。
辛辛苦苦吸引來的用戶變成了系統的攻擊者,把服務器資源耗盡,應用程序崩潰。
你的大多數用戶將丟失,產品評級將降低,市場將充滿負面評論。
所以,可伸縮性已經成為Web應用程序的DNA。
可伸縮應用架構簡介
可伸縮架構的兩個主要原則:
- 關注點分離
- 水平擴展

關注點分離
每個類型的任務都應該有一個獨立的服務器。
有時,應用程序是由一台服務器完成全部工作:處理用戶請求,存儲用戶文件等。
它完成的工作通常應由幾台單獨的服務器完成。
因此,當服務器過載時,整個應用程序將受到影響:頁面無法打開,圖像無法加載等。
為避免這種情況,需要確保關注點分離。
例如,API server 處理需要即時回復的 client-server 請求。
假設某個用戶更改其個人資料圖像,上載圖像後,通常會對其進行一定的處理:調整圖像大小、分析顯式內容、保存在存儲中 ……
顯然,這個過程複雜而耗時,而且用戶不需要等待處理完成。因此,這個任務的優先級較低,因為它不需要一個實時的結果回復。
這是為什麼它不應該放在 API server。

關注點分離對於可伸縮的應用架構至關重要,不僅因為它能夠在專用服務器之間分配不同類型的任務,而且它是水平擴展的基礎。
水平縮放
水平縮放的思想是在多台服務器之間分配負載。
每個服務器都會運行應用,並根據當前負載來啟用或禁用服務器。

負載均衡器控制着所需的服務器數量,保證系統的平滑處理。
負載均衡器知道有多少台服務器在工作、多少在閑置,當發現服務器已經滿負荷,並且請求的數量在增加,那麼他就會激活其他的服務器,重新分配請求負載。
當請求數量降低的時候,他會停用不需要的服務器。
他還會去做服務器的健康檢查,在健康的服務器當中分配請求。
負載均衡器有多種分配請求的算法,例如輪詢、隨機、延遲最小、流量最小等等。這些算法可以考慮諸如地理位置(用戶請求定向到最近的服務器)、每個服務器的工作能力等因素。
水平縮放不需要縮放整個應用,例如,當 API server 達到臨界點時,負載平衡器將激活更多 API server,而不會影響其他服務器。
這就是關注點分離對於水平縮放如此重要的原因之一。
現在,讓我們看看關注點分離和水平縮放如何協同工作。
構建可伸縮的應用

這個示例中,有用於不同類型任務的服務器:
- API server
- 數據庫集群
- 靜態存儲服務器
- Worker,做複雜的、不需要實時反饋結果的任務
每個服務器仍可能是潛在的瓶頸。讓我們一個個地研究它們,看看如何避免它們每個可能出現的可伸縮性問題。
API server
API server 處理主要功能相關的請求,其數量隨着用戶量的增加而增加,
關鍵點是:不要存儲任何的用戶數據,需要無狀態化。
假設用戶上傳圖片的請求是 A 服務器處理的,A 把圖片保存到了本地,下次用戶讀取圖片的請求是 B 處理的,那麼就讀不到圖片了。
還有,負載均衡器隨時可以終止或暫停它們中的每一個。
靜態存儲服務器
靜態存儲服務器與 CDN 配合使用。
CDN 稱為內容交付網絡,是一種緩存服務器,可以將內容立即交付給用戶。

假設你在 YouTube 上觀看了一個有趣的視頻,該視頻存儲在加利福尼亞的靜態存儲服務器中。
你在群聊中發佈該鏈接,如果所有同事同時打開該鏈接,則服務器壓力山大。
有了CDN後,首次打開視頻時,它將被上傳到最近的CDN服務器。
因此,如果您與朋友共享鏈接,則他們將從CDN,而不是直接從靜態存儲服務器請求該鏈接。
這樣防止了靜態存儲服務器過載,用戶還可以享受超快的視頻加載速度。
Worker
並非所有用戶請求都需要服務器的即時答覆。
他們可能需要更多的時間才能完成,這些任務可以在用戶忙於其他事情時在後台運行。
例如,上傳視頻,用戶不會坐下來等視頻處理完畢。
這些任務由 Workers 和 Message Queue 處理。
Worker 在獨立服務器上運行,就像API服務器一樣,可以根據負載強度進行擴展。
Message Queue 就像 API服務器和 Worker 之間的任務管理器。
任務首先到達 Message Queue,當 Worker 不忙時,從隊列中取出並進行處理。如果 Worker 由於某種原因失敗,則任務將保留在隊列中,直到 Worker 恢復或由其他 Worker 處理。

翻譯整理自:
https://medium.com/swlh/how-to-build-scalable-and-highly-available-web-applications-f1d7e7a415be