1. 程式人生 > >大型網站架構總結之網站核心架構要素

大型網站架構總結之網站核心架構要素

架構的含義

一種比較通俗的說法是"最高層次的規劃,難以改變的決定"這些規劃和決定奠定了事物未來發展的方向和最終藍圖。具體到軟體架構,系統的各個重要組成部分及其關係構成了系統的架構,這些組成部分可以是具體的功能模組,也可以是非功能的設計和決策,他們相互關聯組成一個整體。共同構成軟體系統的架構。

5個架構要素:

效能、可用性、伸縮性、擴充套件性、安全性

架構設計中需要平衡這5個要素之間的關係以實現需求和架構目標

效能

效能是網站的一個重要指標,除非沒得選擇(例如:12306)。否則使用者無法忍受一個響應緩慢的網站。

衡量效能手段:響應時間,併發數,吞吐量

效能優化:

效能問題無處不在,所以優化的手段也非常多,從使用者瀏覽器到到資料庫,影響使用者請求的所有環節都可以進行效能優化

Web前端效能優化:

一般來說,Web前端指網站業務邏輯之前的業務,包括瀏覽器載入,網站檢視模型,圖片服務,CDN服務可以通過瀏覽器快取,使用頁面壓縮,合理佈局頁面,減少cookie傳輸,主要優化手段有優化瀏覽器訪問、使用方向代理、CDN等

一、瀏覽器訪問優化:

1、減少http請求:Http是無狀態的應用層協議,意味著每次Http請求都需要簡歷通訊鏈路進行資料傳輸。在伺服器端每個Http都需要獨立的執行緒去處理,這些通訊和服務的開銷都很昂貴,減少Http請求的數目可有效提高效能訪問。主要手段有合併css,合併javaScript,合併圖片(多張圖片通過一張圖片由樣式偏移區分)。

2、使用瀏覽器訪問:對於一個網站而言,CSS、javaScript、Logo、圖示這些靜態資源更新的頻率都比較低,而這些檔案又是每次http請求都需要的,所以可以考慮將這些資源快取在瀏覽器端,可以極好的改善效能。

3、啟用壓縮:在服務端對檔案進行壓縮,在瀏覽器端進行解壓縮,可有效減少通訊傳輸的資料量。

4、減少cookie傳輸:Cookie包含在每次請求和響應中,太大的Cookie會嚴重影響資料傳輸,因此那些資料需要寫入Cookie需要慎重考慮,儘量減少Cookie中傳輸的資料量。

二、CDN(內容分發網路)加速

CDN本質任然是一個快取,而且將資料快取在使用者最近的地方,使使用者以最快的速度獲取資料,即所謂網路訪問第一跳,CDN能夠快取的一般是靜態資源,將其快取在CDN可極大的改善網頁的開啟速度。

三、反向代理

方向代理在網站架構中的作用很多,作為請求總入口,可以保護網站安全(過濾請求等。。)、通過負載均衡改善網站高併發情況下的效能、配置快取(靜態資源)功能加速Web請求。

應用伺服器端優化:

應用伺服器就是處理網站業務的伺服器,網站的業務程式碼都部署在這裡,是網站開發最複雜,變化最多的地方,優化的手段有快取、叢集、非同步等。

一、快取:

網站效能優化第一定律:優先考慮使用快取優化效能。

快取指將資料儲存在較高訪問速度的儲存介質中,以供系統處理。一方面快取訪問速度快,可以減少資料訪問的時間,另一當面如果快取的資料是經過計算處理得到的,那麼被快取的資料無需重複計算可直接使用,因此快取還起到計算計算時間的作用。

網站資料訪問通常遵循二八定律,即80%的訪問落在20%的資料上,因此可以利用將這20%的資料快取起來,可很好的改善系統性能,提高資料訪問能力,降低儲存訪問壓力。

二、非同步操作:

將使用者請求傳送至訊息佇列等待後續任務處理,而當前請求直接返回響應給使用者。

在不使用訊息佇列的情況下,使用者的請求資料直接寫入資料庫,在高併發的情況下,會對資料庫造成很大的壓力,同時也使得響應延遲加劇,在使用訊息佇列後,使用者請求的資料傳送給訊息佇列後立即返回,再由訊息佇列的消費者程序從訊息佇列中獲取資料非同步寫入資料庫,使用者的響應延遲可得到有效改善。訊息佇列還具有很好的削峰作用--即通過非同步處理,將短時間高併發產生的事物訊息儲存在訊息佇列中,從而削平高峰期的併發事務。

三、叢集:

一臺使用者伺服器處理能力始終有限,此時我們應該增加多臺伺服器分擔壓力。

在網站高併發的場景下,使用負載均衡技術作為一個應用構建一個由多臺伺服器組成的伺服器叢集,將併發請求分發到多臺伺服器上處理,避免單一伺服器因負載壓力過大而響應緩慢,使使用者請求具有良好的響應延遲。

可用性

網站可用性:網站可有效訪問特性

對於大型網站而言,特別是知名網站,網站宕掉,服務不可用是一個重大事故。

網站的高可用架構設計的目的就是保證伺服器硬體故障時,服務依然可用,資料依然儲存並能夠被訪問。

主要手段:

實現高可用架構的主要手段是資料和服務的冗餘備份及失效轉移,一旦某些伺服器宕機,就將服務切換到其他可用的伺服器上,如果磁碟損壞,則從備份的磁碟讀取資料。

高可用的應用:

應用層主要處理網站應用的業務邏輯,因此有時也被稱為業務邏輯層,應用的一個顯著特點是應用無狀態性(無狀態應用是指應用伺服器不儲存業務的上下文資訊,而僅根據每次請求提交的資料進行相對應的業務邏輯處理,多個伺服器例項完全對等,請求到任意伺服器,處理結果都是完全一樣的),因此實現叢集很方便,不過也有一些需要注意的地方。

一、通過負載均衡進行無狀態服務的失效轉移

當Web叢集中有一臺應用伺服器宕機時,負載均衡通過心跳檢測機制發現該伺服器失去響應,就會把它從伺服器列表中剔除,而將請求傳送到其他伺服器上面。

二、應用伺服器叢集的Session管理

應用伺服器的高可用架構設計主要基於服務無狀態這一特性,但是事實上,業務總是有狀態的,例如在社交網站中,需要記錄使用者的當前登入狀態,Web應用中將這些多次請求修改使用的上下文物件稱作會話(Session)。在單機應用中,會話交由Web容器管理(tomcat等),在叢集中,請求可能被分發到任意一臺應用伺服器中,所以擺正每次請求依然能夠獲得正確的Session比單機要複雜的多,通過在叢集中有以下手段處理Session問題

1、Session複製:

顧名思義,多臺伺服器之間進行Session的複製,這種方案早期有被使用,而現在有的大型網站核心應用叢集就是數千臺伺服器,這種方案顯然不合理。因此這種方案只適合小型叢集。

2、利用Cookie記錄Session:

將Session記錄在客戶端,每次請求伺服器的時候,將Session放在請求中傳送給伺服器,伺服器處理完請求後再將修改過的Session響應給客戶端。

利用Cookie記錄session也有一定的缺陷,比如受Cookie大小限制(H5新增LocalStore容量比cookie大)能記錄的資訊有限、還有一個前面有提到過,每次請求都需要傳輸Cookie影響效能、如果使用者關閉Cookie,訪問就會不正常。但是由於Cookie的簡單易用,可用性高,支援應用伺服器的線性伸縮,而大部分應用需要記錄的Session資訊又比較小。因此事實上,許多網站都或多或少地使用Cookie記錄Session。

3、Session伺服器;

session伺服器是現在常用的解決方案,利用獨立部署的Session伺服器(redis比較常用)統一管理Session,應用伺服器 每次讀寫Session時,都訪問Session伺服器。

這種解決方案事實上是將伺服器的狀態分離,分為無狀態的應用伺服器和有狀態的Session伺服器,然後針對這兩種伺服器的不同特性分別設計其架構。

高可用的服務:

可複用服務模組為業務產品提供基礎公共服務,大型網站中這些服務通常都獨立分散式部署,被具體應用遠端呼叫。可複用的服務和應用一樣,也是無狀態服務,因此也可以通過負載均衡結合叢集實現高可用,不過有一些服務策略需要注意。

一、分級管理

運維上將伺服器分級管理,核心應用和服務優先使用更好的硬體。

二、超時設定

由於伺服器宕機、執行緒死鎖等原因,可能導致應用程式對服務端呼叫失去響應,進而導致使用者請求長時間得不到響應。在應用程式中設定超時時間,一旦超時,通訊框架丟擲異常,應用程式根據服務排程策略,選擇轉移或者重試。

三、非同步呼叫

高可用的資料

對許多網站而言,資料是其最寶貴的資源,保護網站的資料就是保護企業的命脈。

一、資料備份

資料備份是一種古老又有效的資料保護手段。通常有資料冷備和資料熱備份兩種方案。資料冷備指的是定期將資料複製到某種儲存介質中,一旦系統儲存損壞,就送冷備的儲存資料中恢復資料。資料熱備份就是現在常見的主從複製,讀寫分離。操作資料時,對主資料庫進行寫入操作,之類同步至從資料庫。

二、失效轉移

資料伺服器叢集和應用伺服器叢集並無差異,宕機時需要轉移。

伸縮性

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

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

不同功能進行物理分離實現伸縮:

網站發展早期--通過增加伺服器提高網站處理能力時,新增伺服器總是從現有伺服器中分離部分功能和服務。每次分離都會有更多地伺服器加入網站,使用新增的伺服器處理某種特定的服務。

單一功能通過叢集規模實現伸縮:

將不同的功能分離部署可以實現一定程度的伸縮性,但是隨著網站訪問量的逐步增加,即時分離到最小粒度的獨立部署,單一的伺服器也不能滿足業務規模的要求。因此必須使用伺服器叢集,即將相同服務部署在多臺伺服器上構成一個叢集整體對外提供服務。

一個具有良好伸縮性架構設計的網站,其設計總是走在業務發展的前面,在業務需要處理更多的訪問和服務之前,就已經做好充足準備,當業務需要時,只需要購買或者租用伺服器簡單部署實施就可以了。

擴充套件性

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

主要手段

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

如果模組之間不存在直接呼叫,那麼新增模組或者修改模組就對其他模組影響最小,這樣系統的可擴充套件性無疑更好一些。訊息佇列(kafka等)利用釋出--訂閱模式工作,訊息傳送者釋出訊息,一個或者多個訊息接收者訂閱訊息。對新增業務,只要對該類訊息感興趣,即可訂閱該訊息,對原有系統和業務沒有任何影響,從而實現網站的可擴充套件設計。

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

使用分散式服務是降低系統耦合性的另一個重要手段。如果說分散式訊息佇列通過訊息物件分解系統耦合性,不同子系統處理同一個訊息;那麼分散式服務則通過介面分解系統耦合性,不同子系統通過相同的介面描述進行服務呼叫。

安全性

衡量網站安全架構的標準就是針對現存和潛在的各種攻擊與竊密手段。是否有可靠的應對策略。

XSS攻擊

XSS攻擊即跨站點指令碼攻擊,指黑客通過纂改網頁,注入惡意的HTML指令碼,在使用者瀏覽網頁時,控制使用者瀏覽器進行惡意操作的一種攻擊方式。

防護手段主要有

1、消毒:

XSS攻擊者一般都是通過在請求中嵌入惡意指令碼達到攻擊的目的,這些指令碼是一般使用者輸入中不使用的,如果進行過濾和消毒處理,即對某些HTML關鍵字元轉義(“>“轉義成“&gt”),就可以防止大部分攻擊。

2、HttpOnly:

最早由微軟提出,即瀏覽器禁止頁面JavaScript訪問帶有HttpOnly屬性的Cookie。對於敏感資訊的Cookie(如使用者認證資訊),可通過對該Cookie新增HttpOnly屬性,避免被攻擊指令碼竊取。

sql注入攻擊

攻擊者在http請求中注入惡意SQL命令,伺服器用請求引數構造資料庫SQL命令時,惡意SQL被一起構造,並在資料庫中執行。

防護手段主要有

1、消毒:

和防XSS攻擊一樣,請求引數消毒是一種簡單粗暴又有效的手段。

2、引數繫結:

使用預編譯手段,繫結引數是最好芳SQL注入方法。目前許多資料訪問層框架,如mybatis,Hibernate等,都實現SQL預編譯和引數繫結,攻擊者的惡意SQL會被當做SQL的引數,而不是SQL命令被執行。

CSRF攻擊

CSRF(跨站點請求偽造),攻擊者通過跨站點請求,以合法使用者的身份進行非法操作,主要手段是利用跨站請求,在使用者不知情的情況下,以使用者的身份偽造請求。其核心是利用瀏覽器Cookie和Session策略,盜取使用者身份。

防護手段主要有:

1、表單Token

CSRF是一個偽造使用者請求的操作,所以需要構造使用者請求的所有引數才可以。表單Token通過在請求引數中增加隨機數的辦法來阻止攻擊者獲得所有請求引數:在頁面表單中增加一個隨機數作為Token,每次響應頁面的Token都不相同,從正常頁面提交的請求會包含改Token值,而偽造的請求無法獲得該值,伺服器檢查請求引數中Token的值是否存在並且正確以確定請求提交者是否合法。

2、驗證碼

相對來說,驗證碼更加簡單有效,即請求提交時,需要使用者輸入驗證碼,以避免在使用者不知情的情況下被攻擊者偽造請求。但是驗證碼是一個糟糕的使用者體驗,所以請在必要時使用,如支付交易等關鍵頁面。

3、Referer check

HTTP請求頭的Referer域中記錄著請求來源,可通過檢查請求來源,驗證是否合法。

總結

效能、可用性、伸縮性、擴充套件性和安全性是網站架構最核心的幾個要素,這幾個問題解決了,大型網站架構設計大部分挑戰也就克服了。有一個誤區需要注意,網站技術是為業務而存在的,不要為了技術而技術,選擇適合自身的才是最好的。