看見一篇很是通俗易懂且適合新手閱讀的Web應用架構文章,我將其手工翻譯了出來,分享給你們。php
也能夠去閱讀英文原文,標題爲,貼出連接:程序員
stephenmann.io/post/whats-…web
英文標題爲:數據庫
What's in a Production Web Application?安全
在我職業生涯的早期,我曾在一家工做內容爲構建Web內容管理系統的公司工做。他們的產品幫助營銷部門能夠本身管理網站的內容,而不是依靠開發人員來管理網站。該產品幫助他們的客戶下降了運營成本,並幫助我學習如何構建Web應用程序。bash
雖然產品自己有一個很是普通的用途,但其客戶缺傾向於使用它來解決很是特殊的問題。這些問題以各類眼花繚亂的方式將對產品的要求推到了極限,而且要求該產品必須提供解決方案。在這種環境中工做了十多年,讓我對生產環境下的Web應用程序有了全面的瞭解,其中一些咱們將在本文中討論。服務器
這些年我學到的經驗之一是,對於開發Web應用程序,個別工程師傾向於很是深刻地瞭解他們感興趣的東西,對於不感興趣但必要的組件缺只學習皮毛,這實際上是很是「危險」。這對於具備良好溝通的工程師團隊來講很是有效,由於這些組合知識將重疊以填補任何我的的侷限。然而,這對於獨立工程師或者在這方面經驗不足的團隊,就顯得「危險」。網絡
若是你是在這樣的環境中開始,而後開始從頭開始構建和部署整個Web應用程序,你可能很快就會理解我說的「危險」的意思。架構
業界已經提供了許多旨在解決這個問題的解決方案:託管Web應用程序(Beanstalk,AppEngine等),託管容器管理(Kubernetes,ECS等等)以及許多其餘解決方案。一旦你啓動並運行它們,它們就能夠正常工做,我認爲它們在解決問題方面作得很好。它們隱藏了啓動和運行Web應用程序所需的大量複雜性,而且它們傾向於「恰好能工做」。app
不幸的是,當它不是「恰好能工做」,或者當你須要完成一些特殊的業務時,你可能會發現本身會但願更多地瞭解那個不祥的黑盒子。
在這篇文章中,我將採用一個不可靠的系統,並將其演變爲具備合理可靠性的系統。沿途的每一步都將使用現實中會遇到的問題做爲進入下一步的目的。我沒有討論一個最終設計的每一部分,而是使用這種增量方法有助於讀者瞭解本身的需求,以及本身目前處於哪一步。咱們將從頭開始構建託管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可以讓你輕鬆上手。在這個時候,你還發現博客文章中的分層圖表應該從上到下而不是從左到右顯示圖層。:)
你再次將你的網站發佈到Hacker News。 它撐住了巨大的流量,取得了極大的成功!
這一切彷佛都很棒,直到有一天,你去檢查了你的日誌。 這時你才發現,檢查一第二天志,須要一個小時,由於要檢查12臺服務器(每一個環境中有4臺服務器),這顯得很麻煩。幸運的是,你的公司如今已經賺了足夠的錢來實現ELK堆棧(ElasticSearch,LogStash,Kibana),你構建了一個ELK環境並將它用在了全部環境中。
這樣一來,你能夠輕鬆地查看日誌了,你發現,有不少奇怪的東西混在了日誌裏。
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
複製代碼
你根本沒運行過任何PHP有關的服務,這很是使人擔心。 你注意到數據庫服務器上也有相似的可疑日誌,如今你很想問本身爲何將它們的端口暴露在了外網上,是時候區分公共和私人子網了。
OK,你又開始檢查你的日誌。黑客仍是能夠攻擊你,但如今它們僅限於負載均衡器上的端口80,由於你的應用程序服務器,數據庫服務器和ELK堆棧再也不暴露在互聯網上,這下你舒坦了。
儘管進行了集中式日誌記錄,但你仍是不得不經過手動檢查日誌來發現中斷。 你可使用Amazon CloudWatch設置磁盤,CPU和網絡警報,以便在達到80%容量時向你發送電子郵件。還能說什麼,簡直完美。
開玩笑!沒有一路順風的事情,總有事情會出錯。幸運的是,你有不少工具能夠更輕鬆地處理這些問題。
咱們構建了一個可擴展的Web應用程序,包括備份,回滾,集中式日誌記錄,監控和警報。這是一個很好的總結時刻,由於這裏的增加每每取決於特定應用的需求。
業界提供了許多託管選項,能夠爲你處理大部份內容。你能夠依靠Beanstalk,AppEngine,GKE,ECS等,而不是本身構建全部這些服務。大多數這些服務都會自動設置合理的權限,負載均衡器,子網等。他們須要花費不少麻煩才能使應用程序快速啓動並運行,這樣能夠確保你的站點長時間運行所需的可靠性。
不管如何,我認爲了解這些平臺提供的功能以及提供它們的緣由是有用的。它能夠根據你本身的需求更輕鬆地選擇平臺。一旦你在平臺上運行了全部東西,你就已經弄清楚了這個工具的這些重要方面是如何工做的。當出現問題時,有助於瞭解你擁有解決問題的必要工具。
這篇文章跳過了不少細節問題。它不包括如何自動建立基礎結構,如何配置服務器或如何配置服務器。它不包括如何建立開發環境,如何設置連續交付管道,或如何執行部署或回滾。它不包括網絡安全,祕密共享或最小特權原則。它不包括不可變基礎架構或無狀態服務器或遷移的重要性。這些主題中的每個都須要本身的帖子。
本文的目的主要是提供一個合理的生產Web應用程序應該是什麼樣子的高級概述。 將來的帖子能夠參考這個並擴展它。
感謝你的閱讀!
編者注:編輯:不要使用文章中出現過的具體數值做爲你服務的參數設置。