1. 程式人生 > 實用技巧 >通俗易懂的生產環境Web應用架構介紹

通俗易懂的生產環境Web應用架構介紹

前言

看見一篇非常通俗易懂且適合新手閱讀的Web應用架構文章,我將其手工翻譯了出來,分享給大家。

也可以去閱讀英文原文,標題為,貼出連結:

https://stephenmann.io/post/whats-in-a-production-web-application

英文標題為:

What's in a Production Web Application?

正文

在我職業生涯的早期,我曾在一家工作內容為構建Web內容管理系統的公司工作。他們的產品幫助營銷部門可以自己管理網站的內容,而不是依靠開發人員來管理網站。該產品幫助他們的客戶降低了運營成本,並幫助我學習如何構建Web應用程式。

雖然產品本身有一個非常普通的用途,但其客戶缺傾向於使用它來解決非常特殊的問題。這些問題以各種眼花繚亂的方式將對產品的要求推到了極限,並且要求該產品必須提供解決方案。在這種環境中工作了十多年,讓我對生產環境下的Web應用程式有了全面的瞭解,其中一些我們將在本文中討論。

這些年我學到的經驗之一是,對於開發Web應用程式,個別工程師傾向於非常深入地瞭解他們感興趣的東西,對於不感興趣但必要的元件缺只學習皮毛,這其實是非常“危險”。這對於具有良好溝通的工程師團隊來說非常有效,因為這些組合知識將重疊以填補任何個人的侷限。然而,這對於獨立工程師或者在這方面經驗不足的團隊,就顯得“危險”。

如果你是在這樣的環境中開始,然後開始從頭開始構建和部署整個Web應用程式,你可能很快就會理解我說的“危險”的意思。

業界已經提供了許多旨在解決這個問題的解決方案:託管Web應用程式(Beanstalk,AppEngine等),託管容器管理(Kubernetes,ECS等等)以及許多其他解決方案。一旦你啟動並執行它們,它們就可以正常工作,我認為它們在解決問題方面做得很好。它們隱藏了啟動和執行Web應用程式所需的大量複雜性,並且它們傾向於“剛好能工作”。

不幸的是,當它不是“剛好能工作”,或者當你需要完成一些特殊的業務時,你可能會發現自己會希望更多地瞭解那個不祥的黑盒子。

在這篇文章中,我將採用一個不可靠的系統,並將其演變為具有合理可靠性的系統。沿途的每一步都將使用現實中會遇到的問題作為進入下一步的目的。我沒有討論一個最終設計的每一部分,而是使用這種增量方法有助於讀者瞭解自己的需求,以及自己目前處於哪一步。我們將從頭開始構建託管Web應用程式託管服務所提供的基本結構,並希望能夠詳細介紹每個部分存在的意義。

讓我們開始

讓我們假設你有一年500美元的託管預算,因此你決定從Amazon AWS租用一臺t2.medium伺服器。 在撰寫本文時,每年僅花費約400美元。

你事先知道你需要設計登入系統,並且你需要儲存使用者資訊,因此你需要一個數據庫。 由於預算有限,讓我們在我們唯一的伺服器上託管它。 最終得到的結構如下:

看起來足夠了,哈哈。 事實上,它可能會穩定工作很長一段時間。因為你網站的體量還很小。 此時,你可能每天最多隻能處理10次訪問。 一個小例項可能已經足夠了,但由於你對公司的發展持樂觀態度,因此你使用t2.medium例項做出了不錯的選擇。

你的業務價值儲存在該資料庫中,因此非常重要。你應該確保就算該伺服器發生故障,不會導致你的資料丟失。所以最好去確保下你沒有將資料庫內容儲存在臨時磁碟上,不然的話,如果例項被刪除,你將丟失所有資料。這會非常可怕。

此外,你還應確保將備份轉到外部儲存。AWS S3似乎是一個放置這些的好地方,它相對便宜,所以讓我們設定它。而且你肯定應該通過每隔一段時間做一次資料備份來測試它是否正常工作。

你的結構現在應該如下所示:

在這時,你已經提高了資料庫的可靠性,接下來,你想通過對伺服器執行負載測試來為可能到來的大規模的黑客新聞流量(譯者注:原文為Hacker News,一個資訊源資訊網站)峰值做好準備。一切似乎進展順利,直到500錯誤開始出現,然後是404流,所以你要調查弄清楚發生了什麼。

事實證明,你沒有任何線索來得知網站崩潰到底是因為什麼原因,因為你把日誌寫到控制檯,而沒有將控制檯輸出傳遞到日誌檔案中。你還看到該程序未執行,因此你默認了這就是你獲得404的原因。你臉上的緊張情緒稍稍緩解了點,並且慶幸還好自己沒有直接將你的網站登記到Hacker News上。

你建立了一個執行Web伺服器的systemd服務來保證你的服務會在崩潰後自動重啟。此外,你最終解決了日誌記錄問題。然後你執行另一個負載測試,以確保你已經解決了所有問題。

你又看見了500錯誤(幸好沒有404),你檢查日誌以查看出錯的地方。你發現數據庫連線池已經飽和,該連線池設定為10。你更新了引數,重新啟動資料庫,然後再次執行負載測試。一切順利,所以你決定在Hacker News上推廣你的網站。

釋出日

臥槽!!!(譯者注:Great Scott!!!諺語)你的服務大受歡迎。你進入了Hacker News的頭條。你在30分鐘內獲得5,000次點選,你看到評論湧入了進來。來看看他們怎麼說?

我得到了404,所以我必須檢查頁面的存檔版本。如果有人需要,這是連結:...

媽的空白頁啊!我禁用了Javascript,為什麼網站作者會覺得我會取讀取你的2 MB Javascript檔案 ...

你的主頁需要4秒鐘才能載入。我居住在澳大利亞,Traceroute顯示伺服器託管在德克薩斯州的某個地方。另外,為什麼你的網頁需要2 MB的Javascript?

在混亂中,你被迫在伺服器上設定了Nginx作為應用程式的反向代理,並將其配置為伺服器靜態404頁面。 還將靜態檔案推送到AWS S3,這樣做是為了讓CloudFront CDN能夠起作用,來減少澳大利亞使用者的訪問時間。

這時候你已經解決了當前的問題,這之後,你可以隨時訪問伺服器並檢視日誌。 但你慢慢發現,你的SSH連線非常遲鈍。經過檢查,你發現你的日誌檔案已經完全耗盡了你的磁碟空間,這會使你的程序崩潰並阻止它再次啟動。你建立一個更大的磁碟並在其上掛載日誌。 你還設定了滾動日誌來防止日誌檔案再次變得非常巨大。

效能問題

幾個月過去了。你的使用者群在慢慢增長。你的網站開始變慢。你在CloudWatch監控中注意到,這似乎只發生在中午和晚上。由於變慢的開始和結束時間每天都相同,你猜測這是由於伺服器上的計劃任務造成的。你檢查了你的crontab,看見了你自己在午夜安排了一份工作:備份資料庫。果然,你的備份需要12個小時,並且備份程式使資料庫過載了,導致了網站訪問極慢。

發現了這個問題後,你決定新建一個從資料庫,並在從資料庫上執行備份。 所以你建立了一個從資料庫。在同一臺伺服器上執行從資料庫沒有多大意義,你決定,是時候擴充套件了!你建立兩個新伺服器:一個用於master資料庫,另一個用於slave資料庫。 你將備份更改為在從屬資料庫中定時執行。

組建團隊

一切都執行平穩了一段時間,幾個月過去了,你聘請了一個更大的開發團隊,其中一位新開發人員發現了一個bug,這個bug會導致生產伺服器的崩潰。此位程式設計師覺得是由於開發環境與生產不同導致的。他說的話有些道理,你聽起來覺得很對,所以你決定把這個問題解決。

你構建了更多不同的環境:Staging,QA和生產環境。幸運的是,你從寫這個專案第一天開始就搭建了自動基礎架構,因此環境的增加很容易。並且從第一天起,你就使用了良好的持續交付機制,因此你可以輕鬆地從管道構建新分支。

在這之後,營銷部門希望推出v2.0版本。你不確定v2.0版本是什麼,但無論如何你還是決定做了。是時候準備另一次流量的飆升了。在Web伺服器上執行的服務已經接近伺服器的峰值利用率,因此你決定開始對流量進行負載平衡。亞馬遜ELB能夠讓你輕鬆上手。在這個時候,你還發現部落格文章中的分層圖表應該從上到下而不是從左到右顯示圖層。