楠木軒

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

由 睢風娥 釋出於 科技

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協議。