Web 應用架構基礎課(轉載)

Web 應用架構基礎課

初級 web 應用開發者必學的基礎網絡架構概念

web 應用主流架構概覽php

上圖即是我司(Storyblocks)網絡架構的很好展示。若是你還沒成爲經驗老道的 web 工程師,可能以爲上圖巨複雜。在詳解各個模塊前,咱們先簡單過一下流程。html

用戶在 Google 搜索關鍵字 「Strong Beautiful Fog And Sunbeams In The Forest」, 首條結果即是來自我司的拳頭產品:Storyblocks —— 圖片矢量圖素材站,用戶點擊搜索結果進入圖片詳情頁。在用戶操做的背後,客戶端瀏覽器向 DNS 服務器查詢圖片所在服務器,併發送訪問請求。
用戶請求經過負載均衡(隨機選擇多個服務器中的一個)訪問站點處理請求。服務器從緩存服務中查找圖片信息,並從數據庫中調取其它信息。咱們注意到此時,圖片還沒有進行色彩渲染計算,便發送「色彩渲染」任務到任務隊列。此時該服務所在服務器異步處理任務,適時將結果更新到數據庫。
接下來,咱們嘗試匹配類似圖片,以圖片標題做爲輸入,進行全文搜索服務。用戶登入系統,系統經過帳戶服務查找帳戶信息。最後,系統將該頁面查看事件做爲日誌流處理並在雲存儲系統中記錄,再錄入數據倉庫,供數據分析師作以後的商業分析。
服務器將渲染的 HTML 頁面先通過負載均衡,再返回到用戶瀏覽器。頁面包含 Javascript 腳本和 CSS 資源文件,存於與咱們的 CDN 相連的雲端存儲系統中,用戶瀏覽器直接經過 CDN 獲取內容。最後,瀏覽器顯式地渲染頁面,供用戶瀏覽。

下面,咱們就每個組件詳細討論,作最最基礎的介紹,幫你建構認知模型,思考整個前面提到的整個網絡服務架構。以後我還會發布其它文章,基於在我司學習到的內容,爲你們更有針對性地從實踐角度作推薦。mysql

1. DNS

DNS(Domain Name Server)是域名服務器的簡稱,它是互聯網依存的基礎設施。簡單來講,DNS 提供域名與 IP 地址的鍵值對查找,例如( 域名對應 85.129.83.120 IP 地址),這很是有必要,它讓你的電腦經過請求尋路到特定服務器。就比如打電話,域名與 IP 地址的關係相似於聯繫人和電話號碼的關係。之前你須要電話號碼簿記錄他人的電話號碼,如今你須要 DNS 服務器尋找域名對應的 IP 地址。因此你能夠把 DNS 想象成互聯網世界的電話簿。web

這裏咱們還有不少細節能夠深刻,暫時先跳過,由於這不是咱們基礎課的重點。算法

2. 負載均衡

在詳解負載均衡以前,咱們先退一步討論一下應用的縱向擴展和橫向擴展。二者有什麼區別?簡單來講,參考 StackOverflow 的這篇帖子,橫向規模擴展意味着經過在資源池中加機器,縱向擴展意味着在已有機器上加強算力(如 CPU,RAM)。sql

在 web 開發絕大多數狀況下,會選擇橫向擴展。理由很簡單,服務器會宕機,網絡會斷線,數據中心會掉電。多臺服務器能夠保證你的應用在可以一邊停機維護,一邊持續工做。換句話說,應用可以「容錯」。另外,橫向擴展能最小限度地耦合不一樣後臺服務(web 服務器,數據庫,等等),使不一樣服務在不一樣機器上運行。還有一點,縱向擴展是有上限的,到達必定限度就沒法再擴展。世界上也不存在一臺超算計算機承載應用的全部計算,典型例子想象一下 Google 的搜索平臺,哪怕其它公司達不到這麼大的規模。其它公司,好比我司,Storyblocks,任什麼時候候都把服務跑在 150-400 個 AWS EC2 實例上。經過縱向擴展提供算力是至關有挑戰的。mongodb

回到負載均衡,能夠說它是橫向擴展的黑魔法。它將傳入請求轉路到多個服務器中的其中一個,再將響應回傳給客戶端。多個服務器彼此做爲鏡像,任意機器都會以一樣的方式處理請求。向服務集羣分發消息,便不會出現單個服務器過載的狀況。數據庫

理論上負載均衡就這些要點,很簡單直接。固然了,簡單的理論背後有更多細節,這篇入門文章裏咱們再也不贅述。apache

3. Web 應用服務器

從上層角度來看,web 應用服務器相對好理解,它們用來處理核心業務邏輯,處理用戶請求,給客戶端瀏覽器返回 HTML。處理這些任務即是與後臺基礎設施間通訊,好比數據庫、緩存服務、任務隊列、搜索服務、其它微服務和消息/日誌隊列等等。通常狀況下至少兩個應用服務器,或者更多,這些應用服務接入負載均衡,處理用戶請求。瀏覽器

應用服務器的實現一般須要某種特定語言(Node.js, Ruby, PHP, Scala, Java, C# .NET 等)和對應的 MVC 框架上(Node.js 的 Express、Ruby on Rails、Scala 的 Play、PHP 的 Larave 和 Java 的 Spring 等等)。語言和框架的細節咱們這裏不作贅述,有興趣的讀者能夠自行深刻研究。

4. 數據庫服務器

任意現代 Web 應用都使用一個甚至多個數據庫來存儲信息。數據庫用來定義數據結構,對數據進行增刪改查,高級運算操做等等。多數狀況下,web 應用服務器與一個數據庫進行直接通訊,任務服務器同理。另外,每一個後臺服務都有一個本身的數據庫,並與其它的應用隔離。

儘管在本文中,咱們儘可能避免深刻討論架構中的某個特定技術,這裏我仍是想特殊地提一下數據庫中的 SQL 和 NoSQL。

SQL(Structured Query Language)全稱結構化查詢語言,1970 年代發佈,提供了查詢關係型數據庫的一種標準形式,並廣爲大衆接受。SQL 數據庫將數據以表的形式存儲,經過 ID (一般爲 int 整型)這種方式使表之間相互關聯。舉個簡單的例子,咱們想要存儲用戶的歷史地址信息。須要準備兩張表,用戶表 users 和用戶地址表 user_addresses,並經過 user_id 進行關聯,以下圖。表間相關聯是經過在 user_addresses 表中使用 user_id 做爲外鍵實現的。

 

 

若是你不瞭解 SQL,這裏推薦可汗學院的課程學習。在 web 開發中 SQL 很是廣泛,瞭解其基礎做爲應用架構仍是頗有必要的。

NoSQL,如其字面意思,「非-SQL」,是一種新型數據庫,用來應對大規模 web 應用中的海量數據(大部分 SQL 不能很好支持橫向擴展,只能從某些方面支持縱向擴展)。若是你徹底不瞭解 NoSQL,推薦下列文章:

我還想順便提一點,業界一般使用 SQL 做爲 NoSQL 數據庫的表層調用,不懂 SQL 的話仍是頗有必要去學習的,現在的業務場景很難避開它。

5. 緩存服務

緩存服務提供一種簡單的鍵值對數據存儲,使存取信息時間複雜度接近 O(1) 。應用內一般使用緩存服務存儲運算成本高昂的運算結果,再次請求時從緩存中檢索結果,而非在每次請求時都從新計算。緩存內容能夠是數據庫查詢,外部服務調用結果,連接返回的 HTML,等等。下面咱們從真實場景中舉例:

  • 搜索引擎服務(好比百度)會緩存一些常見的查詢結果,好比「狗」,「周杰倫」,而不是在每次查詢時都實時計算。
  • 社交網站服務(好比 Facebook)會緩存每次登錄時用戶看到的數據,好比最近博文,好友,等等。這裏有一篇 Facebook 如何作緩存的文章。
  • 我司(Storyblocks)會緩存服務器端 React 渲染的 HTML 頁面,搜索結果,預輸入結果,等等。

最經常使用到的服務器緩存技術是 Redis 和 Memcache。我以後會在其它文章中深刻討論。

6. 任務隊列及服務器

大部分 web 應用背後都有異步任務在處理,這些任務沒必要直接響應用戶請求。好比說,谷歌須要爬取整個互聯網並創建索引以返回搜索結果,但這實際上並非在你每次搜索時都實時進行,而是經過異步方式爬取網絡結果並更新索引。

異步任務有不少不一樣的方式來完成,最經常使用的是任務隊列。它包含兩部分:正在運行的任務隊列,和一或多個處理任務的服務器(一般稱爲 workers)。

任務隊列存儲了一系列須要異步運行的任務。最簡單的任務調度是 FIFO(先進先出)的方式,不過大部分應用使用按優先級排序的調度方式處理任務。每當一個任務須要被執行,要麼使用統一的調度算法,要麼是按用戶行爲按需調度,該任務便被加入隊列中等待被執行。

舉個例子,我司利用任務隊列,賦能後臺任務以支持營銷活動。咱們用後臺任務編碼多媒體文件如視頻圖片,處理數據如在 CSV 作元數據標記,聚合用戶行爲分析,運行郵件服務好比給用戶發送重置密碼的郵件,等等。咱們最初使用 FIFO 調度任務,後來優化爲優先隊列,以保證時間敏感的操做完成的實時性,好比立馬發送重置密碼郵件。

任務服務器執行任務時,先查看任務隊列中是否有任務須要執行,如有任務便彈出該任務並執行。有不少語言和框架能夠在服務器上使用做爲任務隊列,這裏很少講。

7. 全文檢索服務

在一些應用中,爲用戶提供搜索功能,用戶輸入文字時(查詢語句)應用返回相近結果。這種技術一般指的是「全文檢索」,運用倒排索引快速查找包含查詢關鍵字的文檔。

上圖中例子顯示了三個文檔標題被轉換成倒排索引,經過某些標題關鍵字可以快速檢索文檔。一般停用詞(英文中的:in、the、with 等,中文中:我、這、和、啊等)不會被加入到索引中。

儘管咱們能夠直接經過數據庫作全文檢索,好比 MySQL 支持全文檢索,但一般咱們會跑一個單獨的「搜索服務」計算並存儲倒排索引,並提供查詢接口。目前主流的全文檢索服務是 Elasticsearch,還有 SphinxApache Solr 等選擇。

8. 服務

當應用到達必定的規模,一般傾向於拆分其爲單個應用,做爲「微服務」。外界對這些微服務是不可感知的,但應用內服務間相互通訊。好比我司有各類運維服務和計劃執行服務:

  • 用戶服務 存儲全部平臺網站用戶數據,便捷地提供交叉銷售商機,以及統一的用戶體驗。
  • 內容服務 存儲多媒體文件的元數據,並提供文件下載接口和下載歷史信息等。
  • 支付服務 提供客戶付款信息接口。
  • PDF 導出服務 提供統一接口,將 HTML 轉換成相對應的 PDF 文件並下載。

9. 數據

現在各大公司成敗在於 「如何很好地管理數據」,在應用到達必定規模時規範數據流程。通常來講有:加工數據、存儲數據和分析數據,這三個步驟:

  1. 數據加工 應用響應用戶交互事件,將數據發送到數據流處理平臺(提供流數據處理接口)進行處理。一般原始數據被轉換或加工並傳入另外一個數據流處理平臺。AWS Kinesis 和 Kafka 是此類數據流處理最經常使用的工具。
  2. 數據存儲 原始數據和轉換加工後的數據在雲端存儲。例如 AWS Kinesis 提供叫作 「firehose」 的配置,將原始數據存儲在其雲平臺 Amazon S3 上,使用起來極其方便。
  3. 數據分析 轉換加工後的數據會加載入數據倉庫來作後續分析。我司使用 AWS Redshift 做爲數據倉庫,不少創業公司也都在用,大型公司通常選擇 Oracle 或者其它的數據倉庫服務。當數據量十分龐大時,可能須要用類 Hadoop 的 NoSQL MapReduce 技術來作後續分析。

還有一個步驟沒有在架構圖中繪出:從應用和服務運維數據庫中把數據導入數據倉庫。例如在我司,咱們每晚都會把各個服務的數據存到 AWS Redshift,把核心業務的數據和用戶交互行爲的數據放在一塊兒,提供給咱們的數據分析師一個總體化的數據集。

10. 雲存儲

「雲存儲既簡單,擴展性又好,方便用戶在全網獲取、存儲、分享數據」 —— AWS 雲存儲服務。任意在本地文件系統存儲的文件,你均可以經過雲存儲存取,並用 HTTP 協議經過 RESTful API 訪問並交互。Amazon S3 提供了目前最流行的雲存儲,我司在其上普遍存儲各類東西,從多媒體素材、視頻、圖片、音頻,到 CSS、Javascript 乃至用戶行爲數據等等。

11. CDN

CDN 指的是內容分發網絡,該技術提供一種素材服務,好比存儲靜態 HTML,CSS,Javascript 和圖片。從全網獲取這些靜態素材比從單個源服務器獲取要快的多。它的工做原理是將內容分佈在世界各地的邊緣服務器上,而不是僅僅放在一個源節點上。好比說,下圖中一個西班牙的用戶訪問某個源節點位於紐約的網站,可是頁面的靜態素材經過英國的 CDN 邊緣服務器載入,這樣就避免了冗餘的跨大西洋的 HTTP 請求,提快了訪問速度。

圖片源

這篇文章 更詳細解釋了爲何使用 CDN。總的來講,網絡應用可使用 CDN 來存儲諸如 CSS、Javascript 和圖片視頻等素材,甚至靜態 HTML 網頁。

一些想法

以上即是網絡應用架構基礎課的所有內容,但願這篇文章對你有幫助。接下來我還會發布進階課的文章,詳細研究上述的某些組件。

相關文章
相關標籤/搜索