警告:本文內容是入門級的,大佬請按秩序有序撤離。php
原文地址:Web Architecture 101html
上圖很好的展現了咱們在Storyblocks的架構。若是你是一個新手工程師,可能會以爲這個架構很是複雜。在咱們深刻研究每一個組件的細節以前,首先應該對它們有個大概的瞭解。mysql
當一個用戶在Google搜索「Strong Beautiful Fog And Sunbeams In The Forest」時,第一條結果來自Storyblocks,咱們主要的照片網站。用戶點擊結果就會在瀏覽器中跳轉到圖片詳情頁。在引擎下,用戶的瀏覽器想DNS服務器發送一個請求,查詢如何鏈接Storyblocks,而後向Storyblocks發送請求。web
請求會先到達咱們的負載均衡器,負載均衡器會隨機選擇一個正在運行的服務器來處理請求。服務器先從緩存中查找一部分關於圖片的信息,並從數據庫查找剩餘信息。咱們注意到此時尚未對圖片的顏色進行配置,所以咱們發送「color profile」任務到咱們的任務隊列,處理任務的服務器會異步執行隊列中的任務,而且將結果適時更新到數據庫中。sql
接下來,咱們試圖從使用照片標題在全文檢索服務中找到與輸入的照片類似的照片。若是登陸用戶是Storyblocks的會員,咱們會去帳號服務中查找用戶的相關信息。最後,咱們會把頁面訪問數據發送到數據「firehose」,以便存儲到咱們的雲存儲系統上,並最終落地到數據倉庫中。數據分析師會使用數據倉庫中的數據來解決商業問題。mongodb
到這裏,服務器已經呈現了一個HTML頁面,並經過負載均衡器將它返回給用戶。頁面包含的JavaScript和CSS會放到鏈接了CDN的雲存儲系統中,因此用戶的瀏覽器鏈接CDN取回數據。最後,由瀏覽器給用戶呈現完整的頁面。數據庫
接下來,我會對每一個組件挨個進行簡單的介紹,以求給你創建一個良好的關於學習架構的思惟模型。我會在另一個系列的文章中分享我在Storyblocks這段時間的實踐經驗,給你提供良好的建議。apache
DNS是「Domain Name System」的縮寫,它是使萬維網成爲可能的核心技術。最基礎的DNS提供了域名(例如google.com)和IP地址的(例如85.129.83.120)的鍵值對以供查找,這是計算機路由請求到指定服務器所必需的。類別電話號碼,域名和IP地址的區別就像是「打給哲少」和「撥打201-867–5309」。就像過去你須要一個電話原本查找哲少的電話號碼,現在你須要DNS服務器來查找域名對應的IP地址。因此你能夠認爲DNS就是互聯網上的電話本。後端
關於DNS的細節咱們還能夠展開講不少,但這裏咱們略過,由於這不是入門級介紹所關心的。瀏覽器
在介紹負載均衡器以前,咱們先來討論一下應用的水平和垂直擴展。它們有什麼不一樣呢?這篇帖子介紹的很明白,水平擴展是經過向資源池中增長更多的機器,垂直擴展是在已有的機器中增長更高的配置(CPU、內存等)。
在Web開發中,爲了應對服務器宕機,網絡波動,數據中心不可用等突發狀況,你必定常用橫向擴展,由於它既簡單又快捷。擁有一臺以上的服務器使你的應用程序在部分服務器掉電時仍然能夠正常運行。換句話說,你的程序具備較好的容錯性。其次,橫向擴展容許你經過讓每一個部分運行在不一樣的服務器上來解耦後端的依賴(Web服務器、數據庫、服務 X等)。最後,當你的服務器達到必定規模時可能沒法再進行垂直擴展。由於這個世界上沒有任何一臺計算機的性能好到能夠支撐你全部應用的計算。舉一個典型的栗子——Google的搜索平臺。固然一原則對於多數規模較小的公司也適用,例如Storyblocks就部署了150到400個AWS EC2實例。對於這樣的狀況,要想經過垂直擴展來提供所有計算是一項艱難的挑戰。
咱們再說回負載均衡器,它們使水平擴展成爲可能。它們將傳入進來的請求路由到衆多服務器中的一個,並將響應結果返回給客戶端。這些服務器一般是彼此的克隆或鏡像,它們中的任何一個都應該以相同的方式處理,這樣就經過分發請求的方式解決避免某臺機器出現過載問題。
負載均衡的概念很是簡單,可是實現起來很是複雜。咱們暫且不介紹。
在上層的Web應用服務描述起來很是簡單。它們用來執行主要的業務邏輯,處理用戶請求,並將HTML返回到用戶的瀏覽器。爲了完成任務,它們一般要與各類後端基礎組件交互,好比數據庫、緩存、任務隊列、檢索服務、其餘微服務、數據/日誌隊列等等。如上所述,爲了處理用戶請求,你至少有兩個,一般更多的負載均衡器。
你應該知道應用服務的實現須要選擇一種語言(Node.js、Ruby、PHP、 Scala、 Java、 C# 、.NET等)和對應MVC框架(Node.js的Express,Ruby的Rails,Scala的Play,PHP的Laravel等)。然而深挖這些語言和框架的細節也超出了本文的討論範圍。
每一個Web應用項目都利用一個或多個數據庫來存儲信息。數據庫提供了定義數據結構、對數據的增刪改查、跨數據計算的方法。多數狀況下,Web應用服務器和任務隊列直接通訊。另外每一個後端服務可能都擁有獨立的數據庫。
雖然我一直強調本文不會介紹某個組件的細節,可是若是不提SQL和NOSQL也是一種不負責任的行爲。
SQL的全稱是「結構化查詢語言」,它在18世紀70年代被髮明。它給你們提供了查詢關係型數據集的標準方法。SQL數據庫將數據存儲在經過公共ID(一般是整數)鏈接在一塊兒的表中。讓咱們來看一個存儲用戶歷史地址信息的例子。你可能須要兩張表,用戶表和用戶地址表,它們經過用戶ID鏈接在一塊兒。下圖展現了一個簡化版本。兩個表經過外鍵鏈接。
若是你不是很瞭解SQL,我強烈推薦你學習一下Khan Academy的一門課程。SQL如今已經很是普及了,所以你至少要了解一些基礎知識才能構建你的應用程序。
NoSQL表明「非SQL」,是一種新的數據庫技術集,用於處理大規模Web應用產生的大量數據(大多數SQL不支持水平擴展,而且垂直擴展也只能擴展到某個點)。若是你不瞭解NoSQL,能夠看下面這些介紹:
可是總的來講,業界仍是要將SQL做爲數據庫的統一接口,即便是對菲關係型數據庫,因此若是你還不瞭解SQL的話,就真的要趕快去學習一下了。
緩存服務提供了簡單的kv存儲數據,儘量使保存和查找數據的時間複雜度接近O(1)。應用程序通常把計算比較複雜的結果保存到緩存服務中,以便再次取值時直接從緩存中讀取而不用從新進行復雜的計算。應用可能緩存的信息包括,數據庫查詢的結果,調用外部服務的返回值,一個URL返回的HTML等等。下面是一些實際的例子:
目前應用最普遍的兩種緩存服務是Redis和Memcache。我會在另外一篇文章中對它們進行更深刻的介紹。
不少應用程序須要在後臺異步處理一些和返回結果無關的邏輯。好比,Google爲了提供搜索服務,須要爬取網頁並進行索引。它並非在你每次搜索的時候都去作這件事,而是異步爬取,並更新索引。
雖然如今有不少不一樣的架構都支持異步操做,但最普及的是我所說的「任務隊列」架構。它包含兩個組件:一個任務隊列和至少一個任務服務器來執行隊列中的任務。
任務隊列一般保存一系列須要異步執行的任務。最簡單的規則是先進先出(FIFO),大多數應用按照優先級給任務排序。當應用須要執行一個任務時,不管是定時任務仍是用戶操做,都會把任務放到隊列中去。
還拿Storyblocks舉例,咱們使用一個後臺的任務隊列爲咱們的市場提供支持。咱們會跑一些視頻圖片解碼,處理CSV元數據標記,彙總用戶統計信息,發送重置密碼郵件等任務。咱們一開始採用FIFO的原則,後來改成優先級隊列,以保證有些具備時效性的任務能儘快完成,好比發送重置密碼郵件。
任務服務器用來處理任務。它們輪詢任務隊列以肯定是否有任務要執行以及是否有任務,若是有,就從任務隊列中彈出一個任務來執行。底層語言和框架的選擇很是多,但它們不在本文討論範圍。
許多web應用支持某種搜索功能——用戶輸入文本,應用返回「相關」的結果。支撐這種功能的技術通常稱爲全文檢索,它利用反向索引快速找到包含關鍵字的文檔。
如今某些數據庫也支持檢索功能(好比MySQL已經支持全文檢索),一般是運行獨立的搜索服務來計算和存儲反向索引,並提供查詢接口。目前最受歡迎的全文檢索平臺是Elasticsearch,另外還有一些其餘比較好的平臺 例如Sphinx和Apache Solr。
一旦一個APP達到必定的規模,就會有某些服務被獨立出來運行。它們不會對外暴露,可是能夠和應用內部的服務之間交互。Storyblocks有幾個運營和計劃的服務:
當下,一家公司的生死由他們駕馭數據的能力決定。現在幾乎每一個APP一旦達到必定規模,就須要經過數據管道來收集、存儲和分析數據。典型的管道有三個步驟:
另一個沒有在架構圖中畫出來的一個步驟:將數據從應用程序和服務的操做數據庫加載到數據倉庫中。例如在Storyblocks,咱們每晚將VideoBlocks, AudioBlocks, Storyblocks, account service和貢獻值門戶網站的數據加載到Redshift。經過將核心業務數據與咱們的用戶交互事件數據放在一塊兒,爲咱們的分析師提供了一整個數據集。
「雲存儲是一種簡單、可靠且可擴展的存儲、檢索和共享數據的方法」——來自AWS。你可使用它存儲或多或少的存儲和訪問本地文件系統的任何內容,而且能夠經過HTTP上的RESTful API與其進行交互。Amazon的S3是目前最流行的雲存儲產品,也是咱們在Storyblocks普遍依賴的產品,用於存儲咱們的視頻、照片和音頻資產,咱們的CSS和JavaScript,咱們的用戶數據等等。
CDN的全稱是「Content Delivery Network」,該技術提供了經過Web獲取靜態HTML,CSS,JavaScript和圖像資源的方式,比直接從單個源服務器提供服務要快得多。它的工做原理是在世界各地的許多「邊緣」服務器上分發內容,以便用戶從「邊緣」服務器而不是源服務器下載資源。例以下圖中,一個用戶從西班牙請求源服務器在紐約的網站,可是靜態資源會從在英國的CDN邊緣服務器加載,防止許多緩慢的跨大西洋HTTP請求。
這篇文章進行了更詳盡的介紹。一般web應用應該始終使用CDN來提供CSS,JavaScript,圖片,視頻和其餘資源。某些應用也可能利用CDN來提供靜態HTML頁面。
這是一篇入門級的Web架構總結。但願可以對你有幫助。我但願發佈一系列的進階文章,在接下來一兩年內我會對這些組件進行深刻研究。