1. 程式人生 > >淺談web架構之架構設計(總結)

淺談web架構之架構設計(總結)

架構模式

先來說說模式: 每一個模式描述了一個在我們周圍不斷重複發生的問題及該問題解決方案的核心。這樣,你就能一次又一次地用該方案而不必做重複工作 。

先來說說常見的網站架構模式。這裡沒有涉及具體實現過程,只是簡單介紹其思想和原理,方便日後有用到再深入瞭解。

分層

分層是企業應用系統中最常見的一種架構模式,將系統在 橫向維度 上切分成幾個部分,每個部分負責一部分相對比較單一的職責,然後 通過上層對下層的依賴和呼叫 組成一個完整的系統。

分層 功能
應用層 負責具體業務和檢視展示,如網站首頁以及搜尋輸入和結果展示
服務層 為應用層提供服務支援,如使用者管理服務,購物車服務
資料層 提供資料儲存訪問服務,如資料庫、快取、檔案、搜尋引擎等

分層架構 還可以細分下去 ,比如說應用層可以細分為檢視層和業務邏輯層。服務層可以細分為資料介面層和邏輯處理層。

分層結構對網站支援高併發向分散式發展至關重要,所以 在網站規模很小的時候就應該採用分層的架構,這樣將來網站做大時才能有更好地應對 。

所以說我們在設計一個新專案的架構時,就需要考慮到分層。不能等到日後專案做大了,再重構就耗時耗力了。

分割

上面的分層是將軟體在橫向方面進行切分,而分割是在 縱向方面 對軟體進行切分。 將不同的功能和服務分割開來,包裝成高內聚低耦合的模組單元 。

比如在應用層,將購物、論壇、搜尋、廣告分割成不同的應用,由獨立的團隊負責,部署在不同的伺服器上;

在同一個應用內部,如果規模龐大業務負責,會繼續進行分割,比如說購物業務,可以分割為機票酒店業務、3C業務、小商品業務等更細小的粒度。

分散式

對於大型網站, 分層和分割的主要目的是為了切分後的模組便於分散式部署 。

利用分散式解決網站高併發的問題的同時,會帶來其他問題:

分散式意味著服務呼叫必須通過網路,這可能對效能造成比較嚴重的影響;

  • 伺服器越多,伺服器宕機的概率就越大;

  • 資料的一致性問題,分散式事務難以保證;

  • 開發管理維護困難。

所以說要量力而行,不要為了分散式而分散式。

常用的分散式方案有以下幾種:

  • 分散式應用和服務:將分層和分割後的應用和服務模組分散式部署,使不同應用複用共同的服務,便於業務功能擴充套件。

  • 分散式靜態資源:網站的靜態資源如js、css、圖片等獨立分散式部署,並採用獨立的域名。減輕應用伺服器的負載壓力,並通過獨立域名加快瀏覽器併發載入速度。

  • 分散式資料和儲存:資料量過大,一臺機器無法儲存。

  • 分散式計算:後臺業務需要處理,包括搜尋引擎的索引構建、資料倉庫的資料分析統計。通過Hadoop及MapReduce分散式計算框架進行批處理計算

叢集

使用分散式已經將切分後的模組獨立部署,但是 對於使用者訪問集中的模組,還需要將獨立部署的伺服器叢集化 ,多臺伺服器部署相同應用構成一個叢集,通過負載均衡裝置共同對外提供服務。

即使是訪問量很小的分散式應用和服務,也會部署兩臺伺服器構成一個小的叢集,目的就是 提高系統的可用性 。

快取

快取是改善軟體效能的第一手段。有以下幾種方式:

  • CDN:內容分發網路,部署在距離終端使用者最近的網路服務商,在這裡快取網站的一些靜態資源,就可以以最快的速度返回給使用者。

  • 反向代理:反向代理屬於網站前端架構的一部分,部署在網站的前端,當用戶請求到達網站的資料中心時,最先訪問反向代理伺服器,這裡快取網站的靜態資源。

  • 本地快取:在應用伺服器本地快取著熱點資料,應用程式可以在本機記憶體中直接訪問資料,而無需訪問資料庫。

  • 分散式快取:資料量很大時,除了本地快取,還需要分散式快取,將資料快取在一個專門的分散式快取叢集中,應用程式通過網路通訊訪問快取資料

快取有兩個前提條件,一是資料訪問熱點不均衡,某些資料會被更頻繁的訪問,這些資料應該放在快取中;二是資料在某個資料段內有效,不會很快過期,否則快取的資料就會因為已經失效而產生髒讀,影響結果的正確性。

非同步

系統解除耦合的重要手段是非同步,業務之間的訊息傳遞不是同步呼叫,而是將一個業務操作分成多個階段,每個階段之間通過共享資料的方式非同步執行進行協作。

在單一伺服器內部可以通過多執行緒共享記憶體佇列的方式實現非同步,處在業務操作前面的執行緒將輸出寫入到佇列,後面的執行緒從佇列中讀取資料進行處理;

在分散式系統中, 多個伺服器叢集通過分散式訊息佇列實現非同步 ,分散式訊息佇列可以看作記憶體佇列的分散式部署。

冗餘

要保證在伺服器宕機的情況下網站依然可以繼續服務,不丟失資料,就需要一定程度的伺服器冗餘執行,資料冗餘備份。

資料庫除了定期備份,存檔儲存,實現 冷備份 外,還需要進行主從分離,實時同步實現 熱備份 。

自動化

釋出對網站是頭等大事,釋出過程自動化可以有效減少故障。自動化測試,自動化安全監測,自動化部署。自動化監控,自動化報警,自動化失效轉移,自動化失效恢復。

說完了架構模式,我們分別從效能、可用性、伸縮性、擴充套件性和安全性來簡單聊下如何設計。

高效能架構

對於高效能而言,首先需要知道自己的效能低在哪裡,哪裡可以用最低的成本進行顯著提高效能。

效能測試

效能測試是效能優化的前提和基礎,也是效能優化結果的檢測和度量標準。

效能測試指標

主要有 響應時間、併發數、吞吐量、效能計數器 等。

響應時間是系統最重要的效能指標,直觀地反映了系統的快慢。

併發數是系統能夠同時處理請求的數目,反映了系統的負載特性。對於網站而言,指同時提交請求的使用者數目。

吞吐量是單位時間內系統的請求數量,體現系統的整體處理能力。

網站效能優化的目的,除了改善使用者體驗的響應時間,還要儘量提高系統吞吐量,最大限度利用伺服器資源。

前端效能優化

瀏覽器訪問優化

cdn

反向代理

前端優化太多地方都有介紹,不再描述。相比後端架構級別的優化,前端效能提升空間並不是很大。

應用伺服器效能優化

分散式快取

非同步操作,將短時間高併發產生的事務訊息儲存在訊息佇列中

使用叢集,負載均衡

儲存效能優化

RAID 廉價磁碟冗餘陣列HDFS Hadoop分散式檔案系統

高可用架構

網站的可用性描述網站可有效訪問的特性。大型網站的不可用事故直接影響公司形象和利益。

前面說過一個基本的網站架構:

位於應用層的伺服器會通過 負載均衡 裝置將 一組伺服器組成一個叢集共同對外提供服務,當負載均衡裝置通過 心跳檢測 等手段監控到某臺伺服器不可用時,就將其從叢集中剔除,並將請求分發到叢集中其他可用的伺服器上,使整個叢集保持可用,從而實現應用高可用。

位於服務層的伺服器也是通過 叢集方式 是實現高可用。只是這些伺服器被應用層通過分散式服務呼叫框架訪問,分散式服務呼叫框架會在應用層客戶端中實現軟體負載均衡,並通過服務註冊中心對提供服務的伺服器進行心跳檢測,發現有服務不可用,立即通知客戶端程式修改服務訪問列表,剔除不可用的伺服器。

位於資料層的伺服器為了保證宕機時資料不丟失,資料訪問服務不中斷,需要在 資料寫入時進行資料同步複製 ,實現資料冗餘備份。當資料伺服器宕機時,應用程式將訪問切換到有備份資料的伺服器上。

伸縮性架構

網站的伸縮性是指 不需要改變網站的軟硬體設計,僅僅通過改變部署的伺服器數量就可以擴大或者縮小網站的服務處理能力 。

一般來說,網站的伸縮性設計可以分成兩類,一類是根據功能進行物理分離實現伸縮,一類是單一功能通過叢集實現伸縮。前者是不同的伺服器部署不同的服務,提供不同的功能;後者是叢集內的多臺伺服器部署相同的服務,提供相同的功能。

應用伺服器伸縮性設計

應用伺服器的伸縮性主要需要通過負載均衡。

這裡主要談談 負載均衡 的實現方式:

HTTP重定向負載均衡

HTTP重定向伺服器是一臺普通的應用伺服器,其唯一的功能就是根據使用者的HTTP請求計算一臺真實的Web伺服器地址,並將該Web伺服器地址寫入HTTP重定向響應返回給使用者瀏覽器。該方法優點是比較簡單,缺點是瀏覽器需要兩次請求伺服器才能完成一次訪問,效能較差。

DNS域名解析負載均衡

每次域名解析請求都會根據負載均衡演算法計算一個不同的IP返回,這樣多個伺服器就構成了一個叢集,並實現負載均衡。

該方法優點是將負載均衡的工作轉交給DNS,省掉了網站管理維護負載均衡伺服器的麻煩。缺點是控制器在域名服務商那裡,網站無法對其做更多改善和更強大的管理。

事實上, 大型網站部分使用DNS域名解析,利用域名解析作為第一級負載均衡手段,也就是說域名解析得到的一組伺服器並不是實際提供Web服務的物理伺服器,而是同樣提供負載均衡服務的內部伺服器,這組內部負載均衡伺服器再進行負載均衡,將請求分發到真實的Web伺服器上 。

反向代理負載均衡

反向代理伺服器處於Web伺服器前面,所以大多數反向代理伺服器在快取資源的同時也提供負載均衡的功能,管理一組Web 伺服器,將請求根據負載均衡演算法轉發到不同Web伺服器上。優點是部署簡單,缺點是 反向代理伺服器是所有請求和響應的中轉站,其效能可能會成為瓶頸 。

IP負載均衡

在網路層通過修改請求目標地址進行負載均衡。

負載均衡伺服器在作業系統核心程序獲取網路資料包,根據負載均衡演算法計算得到真實Web伺服器IP,將資料目的IPD修改,不需要通過使用者程序處理。處理完成後,響應資料包回到負載均衡伺服器,負載均衡伺服器再將資料包源地址修改為自身IP傳送給使用者瀏覽器。

該方法在核心程序完成資料分發,較反向代理負載均衡有更好的處理效能。但是由於所有請求響應都需要經過負載均衡伺服器,叢集的最大響應資料吞吐量不得不受制於負載均衡伺服器網絡卡頻寬。

資料鏈路層負載均衡

在通訊協議的資料鏈路層修改mac地址進行負載均衡。

負載均衡資料分發過程中不修改IP地址,只修改目的mac地址,通過配置真是物理伺服器叢集所有機器虛擬IP和負載均衡伺服器IP地址一致,從而達到不修改資料包的源地址和目的地址就可以進行資料分發的目的,由於實際處理請求的真實物理伺服器IP和資料請求目的IP一致,不需要通過負載均衡伺服器進行地址轉換,可將響應資料包直接返回給使用者瀏覽器,避免負載均衡伺服器網絡卡頻寬成為瓶頸。這種方式又稱為直接路由方式(DR)。

負載均衡演算法

負載均衡伺服器的實現可以分成兩個部分:

1.根據負載均衡演算法和Web伺服器列表計算得到叢集中一臺Web伺服器的地址。

2.將請求資料傳送到該地址對應的Web伺服器上。

具體的負載均衡演算法通常有以下幾種:

  • 輪詢:所有請求依次分發到每臺應用伺服器上,適合於所有伺服器硬體都相同的場景。

  • 加權輪詢:根據應用伺服器效能,在輪詢的基礎上,按照配置的權重分發。

  • 最少連線:記錄每個應用伺服器正在處理的連線數,將新到的請求分發到最少連線的伺服器上,這是最符合負載均衡定義的演算法。

分散式快取叢集的伸縮性設計

分散式快取叢集的伸縮性不能使用簡單的負載均衡手段來實現。

分散式快取伺服器叢集中不同的伺服器中快取的資料各不相同,快取訪問請求不可以在快取伺服器叢集中的任意一臺處理,必須先找到快取有需要資料的伺服器,然後才能訪問。 這個特點會嚴重製約分散式快取叢集的伸縮性設計,因為新上線的快取伺服器沒有快取任何資料,而已下線的快取伺服器還快取著網站的許多熱點資料。

分散式快取叢集伸縮性設計的最主要目標就是 讓新加入快取伺服器後應使整個快取伺服器叢集中已經快取的資料儘可能還被訪問到。

以memcached分散式快取叢集為例:

路由演算法負責根據應用程式輸入的快取資料KEY計算得到應該將資料寫入到Memcached的哪臺伺服器或者應該從哪臺伺服器讀取資料。

所以說在分散式快取叢集的伸縮性設計中, 路由演算法很重要 。

簡單的路由演算法可以使用餘數Hash:用伺服器數目除以快取資料KEY的Hash值,餘數為伺服器列表下標編號。目前比較流行的演算法是一致性Hash演算法。

資料儲存伺服器叢集的伸縮性設計

資料儲存伺服器叢集的伸縮性對資料的永續性和可用性提出了更高的要求。

關係型資料庫叢集的伸縮性設計

市場上主要的關係資料都支援 資料複製 功能,使用這個功能可以對資料庫進行簡單伸縮。

主從複製:資料寫操作都在主伺服器上,由主伺服器將資料同步到叢集中其他從伺服器,資料讀操作及資料分析等離線操作在從伺服器上進行。

分庫:不同業務的資料表部署在不同的資料庫叢集上,這種方式的制約條件是跨庫的表不能進行Join操作。

分片:對一些單表資料仍然很大的表,將一張表拆開分別儲存在多個數據庫中。

資料庫中儲存著資料,要想保住叢集擴容後資料一致負載均衡,必須要做資料遷移,將叢集中原來機器中的資料遷移到新新增的機器中。

NoSQL資料庫的伸縮性設計

HBase為可伸縮海量資料儲存而設計,實現面向線上業務的實時資料訪問延遲。HBase的伸縮性主要依賴其可分裂的HRegion及可伸縮的分散式檔案系統HDFS實現。

HBase整體架構如下:

當一個HRegion中寫入的資料太多,HRegion會分裂成兩個HRegion,並將HRegion在整個叢集中進行遷移,是的HregionServer的負載均衡。

可擴充套件性架構

網站的擴充套件性架構設計,就是在對現有系統影響最小的情況下,系統功能可持續擴充套件及提升的能力。

這裡有必要區分一下 擴充套件性和伸縮性 :

擴充套件性:

指對現有系統影響最小的情況下,系統功能可持續擴充套件或提升的能力。表現在系統基礎設施穩定不需要經常變更,應用之間較少依賴和耦合,對需求變更可以敏捷響應。也就是說當系統增加新功能時,不需要對現有系統的結構和程式碼進行修改。

伸縮性:

指系統能夠通過增加(減少)自身資源規模的方式增強(減少)自己計算處理事務的能力。也就是說利用叢集的方式增加伺服器數量,提高系統的整體事務吞吐呢能力。

設計網站可擴充套件架構的 核心思想是模組化 ,並在此基礎上,降低模組間的耦合性,提高模組的複用性。

前面提到過,通過分層和分割的方式進行架構伸縮,分層和分割也是模組化設計的重要手段, 利用分層和分割的方式將軟體分割為若干個低耦合的獨立的子元件模組 ,這些元件模組以訊息傳遞及依賴呼叫的方式聚合成一個完整的系統。

在大型網站中,這些模組通過分散式部署的方式,獨立的模組部署在獨立的伺服器叢集上,從物理上分離模組之間的耦合關係,進一步降低耦合性提高複用性。

模組分散式部署以後具體集合方式主要有 分散式訊息佇列 和 分散式服務 。

利用分散式訊息佇列降低系統耦合性

事件驅動架構通過在低耦合模組之間傳遞事件訊息,以保持模組的鬆散耦合,並藉助事件訊息的通訊完成模組間合作。在大型網站架構中,實現手段為分散式訊息佇列:

訊息佇列使用釋出訂閱模式。分散式訊息佇列原理如下:

訊息佇列伺服器根據訊息訂閱列表查詢訂閱該訊息的訊息消費者應用程式,將訊息佇列中的訊息按照先進先出的原則將訊息通過遠端通訊介面傳送給訊息消費者程式。

利用分散式服務打造可複用的業務平臺

前面說的分散式訊息佇列通過 訊息物件 分解系統耦合性,不同子系統處理同一個資訊;而分散式服務則通過 介面 分解系統耦合性,不同子系統通過相同的介面描述進行服務呼叫。

隨著網站規模越來越大,一個應用中聚合了大量的應用和服務主機:

這種巨無霸應用系統帶來很多問題,比如說編譯、部署困難,程式碼分支管理困難,資料庫連線資源耗盡,新增業務困難等問題。

解決方案就是 拆分 ,將模組獨立部署,降低系統耦合性。分為橫向拆分和縱向拆分。

縱向拆分:將一個應用拆分為多個小應用,如果新增業務較為獨立,那麼就直接將其設計部署為一個獨立的Web應用系統。

橫向拆分:將複用的業務拆分出來,獨立部署成分散式服務,新增業務只需要呼叫這些分散式服務,不需要依賴具體的模組程式碼,即可 快速搭建一個應用系統 ,而模組內部業務邏輯變化時,只要介面一致就不會影響業務程式的其他模組。

縱向拆分相對簡單,通過梳理業務,將較少相關的業務剝離,使其成為獨立的Web應用,而對於橫向拆分,不但需要識別可複用的業務,設計服務介面,規範服務依賴關係,還需要一個完善的分散式管理服務框架。應該具有以下特性:

  • 負載均衡

  • 失效轉移

  • 高效率的遠端通訊

  • 整合異構系統

  • 對應用最少侵入

  • 版本控制

  • 實時監控

大型網站需要更簡單高效的分散式服務框架構建其SOA(Service Oriented Architecture面向服務的體系架構)Facebook利用Thrift管理其分散式服務。國內一般是阿里巴巴的Dubbo。

我們以Dubbo為例,分析其架構:

服務消費程式通過服務介面使用服務,而服務介面通過代理載入具體服務,具體服務可以是本地的程式碼模組,也可以是遠端的服務,因此對應用較少的侵入:應用程式只需要呼叫服務介面,服務框架根據配置自動呼叫本地或遠端實現。

服務框架客戶端模組通過服務註冊中心載入伺服器提供者列表,查詢需要的服務介面,並根據配置的負載均衡策略將服務呼叫請求傳送到某臺服務提供者伺服器。如果服務呼叫失敗,客戶端模組會自動從伺服器列表選擇一個可提供同樣服務的另一臺伺服器重新請求服務,實現 服務的自動失效轉移 ,保證服務高可用。

安全性架構

各種各樣的攻擊手段就不再介紹了。這裡說寫通用的配置吧。

防火牆

ModSecurity是一個開源的Web應用防火牆,探測攻擊並保護Web營業員程式,既可以嵌入到Web應用伺服器中,也可以作為獨立的應用程式啟動。

ModSecurity採用 處理邏輯 與 攻擊規則 集合分離的架構模式,處理邏輯負責請求和響應的攔截過濾,規則載入執行等功能。而攻擊規則集合則負責描述對具體攻擊的規則定義、模式識別、防禦策略等功能。處理邏輯比較穩定,規則集合需要不斷針對漏洞進行升級,這是一種可擴充套件的架構設計,如圖:

資訊加密

資訊加密技術可分為三類:單向雜湊加密、對稱加密和非對稱加密。

單向雜湊加密

指通過對不同輸入長度的資訊進行雜湊計算,得到固定長度的輸出,這個雜湊計算過程是單向的,即不能對固定長度的輸出進行計算從而獲得輸入資訊。常用的演算法有MD5、SHA等。

salt相當於加密的金鑰,可增加破解的難度。網站密碼一般都是用這種演算法來儲存。這樣即使被拖庫,也不會洩露。

對稱加密

指加密和解密使用的金鑰是同一個金鑰(可以互相推算),如圖:

對稱加密通常用在資訊需要安全交換或儲存的場合,如cookie加密、通訊加密等。

對稱加密的優點是演算法簡單,加密效率高,系統開銷小,適合大量資料加密。缺點是加密解密使用同一個金鑰,遠端通訊的情況下如何安全的互動金鑰是個難題,如果金鑰丟失,那麼所有的加密資訊也就沒有祕密可言了。

常用的對稱加密手段有DES、RC演算法。

非對稱加密

加密和解密使用的不是同一金鑰,其中一個對外界公開,被稱作公鑰,另一個只有使用者知道,被稱作私鑰。用公鑰加密的資訊必須用私鑰才能解開,反之用私鑰加密的資訊只能用公鑰才能解開。且不可能通過公鑰算得私鑰。

非對稱加密通常用在資訊保安傳輸,數字簽名等場合。常見的非對稱加密演算法有RSA演算法,HTTPS中瀏覽器使用的數字證書實質上也是。

實際應用中,常常會混合使用非對稱加密和對稱加密,先使用非對稱加密技術對金鑰進行安全傳輸,然後使用對稱加密技術進行資訊加解密與交換。

金鑰安全管理

前面介紹的加密技術都基於金鑰的安全基礎上。如果金鑰洩露,就失去了安全性。實際開發中,經常有工程師把金鑰直接寫在原始碼中,或者是配置檔案中,線上和開發環境配置不同的金鑰。這樣的話,不夠安全。

通過兩種方案改善:

1.金鑰和演算法放在一個獨立的伺服器上,甚至做成一個專用的硬體裝置,對外提供加密和解密服務,用用程式通過呼叫這個服務,實現資料的加解密。這種方法由專人維護,金鑰不容易洩露,但是成本較高。

2.將加解密演算法放在應用系統中,金鑰則放在獨立伺服器中,為了提高金鑰的安全性,實際儲存時,金鑰被切分成數片,加密後分別儲存在不同儲存介質中,兼顧金鑰安全性的同時又改善了效能。

資訊過濾和反垃圾

常見手段:

1.文字匹配

解決敏感詞過濾的問題。通常網站維護一份敏感詞列表,如果使用者發表的資訊含有列表中的敏感詞,則轉義。

快速匹配到敏感詞可以通過正則,效率低。也可以使用Trie演算法。簡單點的可以通過構造多級Hash表進行文字匹配。還可以先進行降噪預處理,放在”敏  詞”這樣的詞彙繞過防禦。

2.分類演算法對於廣告貼、垃圾郵件等內容的識別比較有效的自動化方法是採用分類演算法。

比較簡單實用的分類演算法有貝葉斯分類演算法、TAN演算法、ARCS演算法,一種利用概率統計方法進行分類的演算法。分類演算法除了用於反垃圾,還可以用於資訊自動分類。入口網站可以用該演算法對採集來的新聞稿件進行自動分類,分發到不同的頻道。

3.黑名單將發起人放入黑名單。可以通過Hash表實現,但是如果黑名單列表過大,Hash十分佔用記憶體,可以用布隆過濾器代替Hash表。如果需要精確的判斷,就不適合布隆過濾器了。

風險控制

交易安全是電子商務網站的底線。電子商務具有多種形式,B2B,B2C,C2C每種交易的場景都不相同,風險也各有特點,大致可以分為以下幾種:

  • 賬戶風險:包括賬戶被黑客盜用,惡意註冊賬號等幾種情況

  • 買家風險:買家惡意下單佔用庫存進行不正當競爭;黃牛利用促銷搶購低價商品;

  • 賣家風險: