楠木軒

經驗分享:資深架構師教你什麼是網絡應用架構?

由 睢風娥 發佈於 科技

01 從一個場景開始

以上的架構圖是對 Storyblocks 業務架構的一個很好的概括。對於那些相對缺乏經驗的 web 開發者,或許你會覺得這個架構有些複雜。沒關係,在講解相關組件的具體業務細節之前,我們先舉個例子,幫你更容易地理解 Storyblocks 的業務架構。

先從一個場景開始:用户用谷歌搜索 「美麗的濃霧和林間的陽光」 。首個結果正好出自 Storyblocks:一個知名的圖片和矢量圖資源網站,用户點擊該條結果,瀏覽器重定向到該圖片的所在的詳情頁面。

這個場景背後,用户瀏覽器向 DNS 服務器發送請求,查詢 Storyblocks 的域名信息,然後發送訪問請求。訪問請求首先經過負載均衡器,負載均衡器會從十多台運行網站服務的網絡服務器選擇任意一台,將請求發送到這台服務器進行處理,網絡服務器先從緩存服務器查詢圖片的詳情信息,然後從數據庫獲取圖片的其他相關信息。

我們注意到這張圖片的色彩配置信息還沒被計算出來,於是服務器將一個新的色彩配置任務推送到任務隊列,我們的任務隊列服務器將異步地處理圖片的色彩配置信息計算,一旦計算完成,便將配置信息更新到數據庫中。

下一步,服務器將圖片標題作為關鍵詞,向全文檢索服務發送查詢請求以尋找相似圖片。此時用户登入他的 Storyblocks 賬户,相應地,服務器從賬户服務中獲取用户賬户信息。

接下來,我們將這個頁面瀏覽事件加載到 data firehose(AWS 推出的流數據裝載服務) 以記錄到雲存儲系統,並最終存儲到數據倉庫,便於分析師分析使用並幫助解答業務問題。

服務端將視圖呈現為為 HTML 頁面並經由負載均衡器,返回用户的瀏覽器客户端。這個頁面同時包含存儲在雲存儲系統的 Javascript 和 CSS 代碼文件,雲服務器直接連接到 CDN 集羣,內容也經由 CDN 分發,用户瀏覽器訪問 CDN 集羣並獲取內容。

最終,瀏覽器渲染頁面使用户可以瀏覽閲讀。

接下來,我將帶你遍歷每個組件,並做簡要説明和介紹,幫助你形成一個相對準確的概念模型,以便於理解網絡架構和組件間的交互。我仍將遵循已經分享的文章中給出的一些實踐建議,這些建議基於我在 Stroyblocks 的業務經驗,具有一定參考價值。

02 網絡架構諸組件1. DNS 服務

DNS (Domain Name System)代表 「域名系統」,這是實現互聯網相互連接的核心技術。DNS提供從域名 (例如 google.com) 到 IP 地址 (85.129.83.120) 的最底層的鍵值對查詢服務,事實上,計算機基於網站的 IP 地址路由到合適的服務器。用電話號碼比喻的話:域名和 IP 地址的關係,類似於聯繫人姓名和號碼的關係。

正如你需要通過電話簿來查詢特定聯繫人的電話號碼,你同樣需要通過 DNS 來查詢指定域名的 IP 地址,所以你完全可以把 DNS 理解為互聯網的電話號碼簿。

我們以後會深入介紹關於 DNS 的詳細原理,現在進入下一個話題。

2. 負載均衡

在深入介紹負載均衡之前,我們需要先行解釋應用架構的水平拓展和垂直拓展。

你肯定會好奇這兩個概念的含義和區別:簡單來説,水平拓展是指你向資源池增加更多機器設備,而垂直拓展則意味着增加更多算力資源(CPU,內存)到現有機器設備。對於 Web 開發,水平拓展常常是最好的選擇。

畢竟,所有事物都可能中斷,服務器有時崩潰,網絡會降速,甚至整個數據中心也會偶爾斷線。如果要防止出錯,除了保持簡單,我們別無選擇。使用服務器集羣可以幫你有效應對突發情況,增強業務的健壯性和容錯性,確保應用持續穩定地運行。

其次,水平拓展允許你將後端服務 (網絡服務器,數據庫,應用服務) 的不同組件分配在不同服務器,藉此你可以高效地調用後端服務的不同組件。

最後,垂直拓展很容易遇到規模瓶頸,谷歌的搜索服務平台是一個相當典型的案例,這個場景也同時適用於 Storyblocks 這樣的中小型公司,舉例來説,我們在任意時刻都運行着 150 到 400 個 AWS EC2 實例,如果要通過垂直拓展模式提供同等算力,很難想象我們需要使用何種級別和規模的計算機設備(估計得使用超算了)。

現在我們回到負載均衡器,它們是實現業務水平拓展的重要部分,它們將接收的訪問請求路由到互為備份的應用服務器集羣中的任意一個,並將應用服務器的響應返回到客户端。任何一個應用服務器的處理方式都完全相同,通過這種方式,負載均衡器將訪問請求均勻地分派到不同的服務器以防止服務器過載。

負載均衡器的業務原理相當簡單,但是要深入理解,就涉及到很多複雜的概念,這些更加複雜的概念,我們將在以後進行講解。

3. Web 應用服務器

從抽象角度來説,Web 應用服務器的作用是這樣的:它們被用來執行諸如處理用户請求和將 HTML 返回用户瀏覽器等核心業務邏輯。為了確保任務完成,應用服務器通常會和數據庫,緩存層,任務隊列,搜索服務,其他微服務組件,數據/日誌隊列等一系列後端基礎設施交互。

正如上文所提及,很多時候,由於負載均衡器的存在,應用服務器需要成倍地連接更多服務,以便於處理大規模的用户訪問請求。

應用服務的技術實現首先基於特定後端語言,如 Node.js, Ruby, Scala, Java, C#, .NET 等等,同時需要選擇基於該後端語言的 Web MVC 框架,如 Express 之於 Node.js, Ruby on Rails, Play 之於 Scala, Laravel 之於 PHP 等等。本文僅做基本介紹,不會過於深入介紹這些語言和框架的具體實現細節。

4. 數據庫服務器

任何一個現代的 Web 應用都使用一個或以上的數據庫存儲信息。數據庫幫助我們完成諸如定義數據結構,插入數據,查找數據,更新和刪除數據,以及執行數據計算等各種數據庫操作。

在大多數情況下,Web 應用服務器和專有的數據庫服務器直接通信,對於任務服務器也是如此。另外,任何一個後端服務都可能擁有一個獨立於其他應用的專有服務器。

儘管我在試圖避免在每個組件上過於深入細節,但是如果我不詳細解釋數據庫的一些基礎概念,(SQL 和 NoSQL),必將會影響你理解接下來的其他概念。

SQL(Structured Query Language, SQL),代表 「結構化查詢語言」。被髮明於上世紀七十年代,作為標準的關係數據庫數據查詢方式,最終被廣泛接受和使用。SQL 數據庫將數據存儲在數據表中,通過 ID 等字段進行表關聯。

舉一個簡單的存儲用户歷史地址信息的的例子簡要説明:現有兩個表:【用户表: users】和【用户地址表: user_addresses】,這兩張表通過用户編號相關互聯,如下圖所示。這些表相互關聯,是因為【用户地址表】的 {用户編號: id} 信息是用户表中 {用户編號: id} 在用户地址表的外鍵 (Foreign Key, FK)

如果你對 SQL 不太瞭解,我強烈建議你學習這個基礎教程,可汗學院的 SQL 入門課:數據查詢與數據管理 ,SQL 在 Web 開發領域應用相當廣泛,你至少需要了解基礎知識,這樣才能恰當地設計應用架構。

NoSQL 代表 Non-SQL 或 Not-Only-SQL,是指新一代的數據庫技術,用於處理大型網絡應用所產生的巨量數據(大多數關係型數據庫無法很好地水平拓展,只能垂直拓展,直到性能瓶頸)。如果你對 NoSQL 一無所知,我建議你從以下介紹入手:

值得注意的是,基於 SQL 查詢已經成為數據庫的通行接口標準,即使對於 NoSQL 數據庫也是如此。所以如果你對 SQL 缺乏瞭解,很有必要認真學習一番,在互聯網行業,SQL 是無可避免的。

5. 緩存服務

緩存服務為相關信息提供簡單的鍵值數據存儲,可在接近 O(1) 時間內保存和查找信息。

應用服務同樣會利用緩存服務預先存儲一些計算量較大的計算結果,以便於下次需要時直接從緩存中獲取結果而重新計算。應用服務也可能從其他服務獲取緩存,如數據庫查詢結果,外部服務調用結果,指定URL 的 HTML 文件,以及其他服務。下面是真實世界的一些案例:

  • 谷歌直接緩存常見的搜索關鍵詞如「狗」或者「泰勒·斯威夫特」的搜索結果,而非搜索時重新計算。
  • Facebook 緩存你登入賬户時所看到的信息,如你的發帖記錄信息和朋友列表信息等數據。這篇文章詳細介紹了 Facebook 的緩存技術應用。
  • Storyblocks 緩存服務端的 React 渲染生成的HTML 文件,搜索結果和提前輸入結果等信息

使用最廣泛的兩種緩存服務器技術是 Redis 和 Memcache,後續也會針對這兩種技術進行介紹。

6. 任務隊列和服務器

在不涉及於用户交互的場景中,網絡應用需要異步地完成很多工作。例如,為了搜索查詢結果,谷歌需要用爬蟲遍歷全網的內容並編制索引,谷歌不是在用户搜索時才進行上述操作,相反,它異步地爬取網絡內容,並預先更新查詢索引。

儘管有很多應用架構可用於完成異步任務,但最通用的是「任務隊列架構 (Job Quene)」。它包括兩個組件:一系列等待被執行的「任務」和數個用於執行任務的任務服務器(通常被稱為 Workers )

任務隊列存儲一系列需要被異步執行的任務。先進先出(First In First Out, FIFO)隊列是最簡單的任務隊列,儘管多數應用最終需要可以按照優先級排序的隊列系統。不管是由日常任務調度安排或是由用户操作觸發,一旦應用服務需要執行任務,它都會將合適的任務添加到隊列中。

例如,Storyblocks,將任務隊列用於強化那些用於支持市場的幕後工作:例如視頻和圖片的編碼,包含元數據標籤的 CSV 的處理,用户統計數據的聚合,密碼重置郵件的發送等任務。起初我們使用簡單的 FIFO 隊列,但最終我們還是升級為優先級列隊以確保那些時間敏感的任務可以迅速完成(如密碼重置郵件的發送)

任務服務器的任務處理流程為:任務服務器輪詢任務隊列以確定是否有任務需要執行,如有則推出(pop)該任務並加以執行。相關的編程語言和服務框架數不勝數,這裏就不作過多展開。

7. 全文檢索服務

當用户輸入文字進行查詢時,多數網絡應用都或多或少地提供檢索功能,應用服務返回最相關的查詢結果。這種用於支持文本查詢的功能,通常被稱為「全文檢索」,全文檢索使用反向索引以便快速查詢包含關鍵詞的文件信息。

上圖説明如何將這三個文檔標題轉換為反向索引,以便於從特定關鍵字快速查找到標題中具有該關鍵字的文檔。請注意,如 “in”,”with” 等常見單詞,通常不包括在倒置索引中的常見單詞(被稱為停止詞: stop words)

儘管有些數據庫直接提供全文檢索特性(例如,MySQL 支持全文搜索)但將一般將計算生成並存儲反向索引的「檢索服務」作為獨立服務並提供查詢接口。現在最流行的全文檢索平台是 Elasticsearch,同時 Sphinx 和 Apache Solr 也是常見的備用選擇。

8. 服務

當應用達到一定規模,其中有些服務需要拆分出來成為單獨的應用。這些新應用不一定用於開放給外部系統,但是一定會用於和原應用以及其他服務交互。舉例來説,Storyblocks 有以下幾種操作和計劃服務:

  • 賬户服務:存儲用户在我們所有站點的相關數據,這將有助於我們提供交叉銷售的機會並創造統一的用户體驗
  • 內容服務:存儲所有視頻、音頻和圖形內容的元數據,同時為內容下載和查看下載歷史記錄提供接口
  • 支付服務:為處理客户信用卡結算信息提供接口
  • HTML → PDF 服務:提供簡單的處理接口,以支持根據 HTML 頁面返回相應 PDF 文件
9. 數據處理

大數據時代,公司的生死存亡繫於對數據的完善利用程度。現在的網絡應用,只要達到一定業務規模,就一定會建立數據管道以確保數據的收集、存儲和分析。典型的數據管道包括以下三個主要過程:

  • 數據流處理:應用發送數據,特別是關於用户行為的事件信息,到 data firehose,後者提供了流處理接口以攝取和處理數據。通常來説,源數據會經過轉換或處理併發送到另外的 firehose。AWS Kinesis 和 Kafka 是用於此目的的兩種最常見的技術
  • 數據雲存儲:源數據以及經過轉換或處理的新數據將被存儲到雲存儲系統。AWS Kinesis 提供了一種名為 “firehose” 的設置,它幫助我們輕鬆地配置將源數據存儲到雲存儲 (AWS S3) 的整個過程
  • 同步到數據倉庫:經過轉換或處理的新數據常常被裝載到數據倉庫以便於分析。我們也使用 AWS Redshift,它在創業公司中相當普遍且份額正逐漸擴大。儘管大公司通常使用 Oracle 或其他專有的數據倉庫技術。如果數據集足夠龐大,對於分析而言,類 Hadoop 的 NoSQL MapReduce 技術將是必要的。

應用架構圖中未提及的一個環節是:將數據從網絡應用和服務的生產數據庫裝載到數據倉庫。比如在 Storyblocks 我們每天裝載視頻塊,音頻塊,故事塊(VideoBlocks, AudioBlocks, Storyblocks)和賬户服務以及參與者門户數據庫到 RedShift。由此通過整合核心業務數據和用户行為事件數據,為數據分析師提供完整的數據集。

10. 雲存儲

按照 AWS 的説法,「雲存儲是一種存儲、訪問和分享數據的方便且可拓展的方式」

和本地文件系統的現有方式一樣,你可以使用雲存儲來存儲和訪問任何文件,其好處是能夠調用 RESTful API 通HTTP 交互。到目前為止,亞馬遜 S3 是市場上最受歡迎的雲存儲服務(國內則是阿里雲),也被 Storyblocks 用於存儲視頻、圖片和音頻資源,還有 CSS 和 Javascript 代碼,以及用户事件數據等信息。

11.CDN

CDN(Content Delivery Network)代表「內容分發網絡」,該技術提供了一種快速加載 HTML、CSS、JavaScript 文件和圖片等網頁資源的方式,這比從原服務器直接請求要要快得多。

CDN 基於遍佈世界各地的「邊緣服務器 (Edge Server)」分發內容,這樣用户可以從邊緣服務器加載網頁資源,而不用訪問原服務器加載。如下圖所示:身在西班牙的用户請求原站點位於美國紐約的網頁,但是靜態網絡資源卻經由CDN 網絡中位於英國的邊緣服務器獲取,而非通過緩慢且不安全的跨洋 HTTP 請求。

想要了解更詳盡的介紹,可以查看本文。通常來説,Web 應用應始終使用 CDN 為 CSS、Javascript、圖像、視頻和任何其他網絡資源提供服務。某些應用還會使用 CDN 來分發靜態 HTML 頁面。

寫在最後

畢竟,我們所設計的產品最終通過互聯網分發給全國和世界各地的用户,我們對於互聯網通信過程瞭解越深入,就越有可能發現產品所可能存在的缺陷和問題,也就越有可能做出真正優秀的產品。

希望各位讀者能夠有所收穫,我也將陸續創作和翻譯其他相關產品和技術的內容和分享。

原文地址: web-architecture-101

題圖來自Unsplash,基於CC0協議。