大型網站架構演變

1、簡介

大型網站架構的演進最開始都是由小及大慢慢演變過來的,任何一個好的架構都不是設計出來的,是經過業務發展迭代而來的,這個觀點我是贊同的。對於網站架構技術非常有興趣,一直持續關注學習架構技術,本次想通過大型網站技術發展歷程,剖析大型網站技術架構模式,深入分析大型互聯網架構設計。這篇文章我們只關注架構的演變歷程。
大型網站架構演變
通過電商業務爲例,該系統的功能有用戶模塊【用戶註冊和管理】、商品模塊【商品展示和管理】、交易模塊【創建交易和管理】。通過圖例分析一個最初從單臺LAMP怎麼發展到龐大的分佈架構體系。

線上系統高可用參考指標:
大型網站架構演變
大型網站架構演變

2、架構演變歷程

2.1. 第一階段【單機構建網站】

網站程序用到的開源框架如maven+spring+struct+hibernate、maven+spring+springmvc+mybatis;網站初期,我們經常會用單機跑所有的程序和軟件。通常由app server 和DB server組成,如tomcat和mysq;最後通過JDBC進行數據庫的連接和操作。
大型網站架構演變

一般5萬pv到30萬pv訪問量,結合內核參數調優、web應用性能參數調優、數據庫調優,基本上能夠穩定的運行。

2.2. 第二階段【應用服務器與數據庫分離】

隨着網站的發展當訪問量逐漸增大,服務器的負載慢慢提高,系統的壓力越來越大,響應速度越來越慢,這個時候比較明顯的是數據庫和應用互相影響,應用出問題了,數據庫也很容易出現問題,而數據庫出問題的時候,應用也容易出問題。在服務器還沒有超載的時候,我們應該提前做好準備,提升網站的負載能力。假如我們代碼層面已難以優化,在不提高單臺機器的性能的情況下,將應用和數據庫從物理上分離,增加機器是一個不錯的方式,不僅可以有效地提高系統的負載能力,而且性價比高。此時我們可以把數據庫、web服務器拆分開來,這樣不僅提高了單臺機器的負載能力,也提高了容災能力。
大型網站架構演變

隨着用戶量的增大、對帶寬需求的增大、對CPU處理能力的增大;不足以融合所有用戶的需求了,或者網站業務量的需求了。此處很少也不應該直接就對它做負載均衡式的擴展,因爲數據同步很麻。所以我們架構擴展,不會上來就直接做負載均衡式的每一組組件當做一個整體來進行擴展,而是功能上切割 。這個時候技術上沒有什麼新的要求,但你發現確實起到效果了,系統又恢復到以前的響應速度了,並且支撐住了更高的流量,並且不會因爲數據庫和應用形成互相的影響。

2.3. 第三階段【應用服務器負載均衡】

隨着訪問量繼續增加,單臺應用服務器已經無法滿足需求了。假設數據庫服務器沒有壓力,我們可以把應用服務器從一臺變成了兩臺甚至多臺,把用戶的請求分散到不同的服務器中,從而提高負載能力。此時我們應該選擇一款合適的負載均衡產品,一般來講keepalived配合上ipvsadm做負載均衡,可謂是神器。這一階段是需要掌握更多基礎知識的關鍵節點。以下可以使用DNS解析對用戶請求做負載均衡:
大型網站架構演變

需要注意:負載均衡產品的選擇、負載均衡算法的選擇、用戶session保持的問題、應用佔用資源的角度選擇合理的服務器配置。
解決方案:根據以下技術特性選擇適合業務的產品、技術。例如nginx+keepalived一臺服務器、apache+tomcat一臺服務器、mysql一臺服務器。

三種負載均衡器的優缺點說明如下:摘自(互聯網)
LVS的優點:
1、抗負載能力強、工作在第4層僅作分發之用,沒有流量的產生,這個特點也決定了它在負載均衡軟件裏的性能最強的;無流量,同時保證了均衡器IO的性能不會受到大流量的影響;
2、工作穩定,自身有完整的雙機熱備方案,如LVS+Keepalived和LVS+Heartbeat;
3、應用範圍比較廣,可以對所有應用做負載均衡;
4、配置性比較低,這是一個缺點也是一個優點,因爲沒有可太多配置的東西,所以並不需要太多接觸,大大減少了人爲出錯的機率;
LVS的缺點:
1、軟件本身不支持正則處理,不能做動靜分離,這就凸顯了Nginx/HAProxy+Keepalived的優勢。
2、如果網站應用比較龐大,LVS/DR+Keepalived就比較複雜了,特別是後面有Windows Server應用的機器,實施及配置還有維護過程就比較麻煩,相對而言,Nginx/HAProxy+Keepalived就簡單多了。

Nginx的優點:
1、工作在OSI第7層,可以針對http應用做一些分流的策略。比如針對域名、目錄結構。它的正則比HAProxy更爲強大和靈活;
2、Nginx對網絡的依賴非常小,理論上能ping通就就能進行負載功能,這個也是它的優勢所在;
3、Nginx安裝和配置比較簡單,測試起來比較方便;
4、可以承擔高的負載壓力且穩定,一般能支撐超過幾萬次的併發量;
5、Nginx可以通過端口檢測到服務器內部的故障,比如根據服務器處理網頁返回的狀態碼、超時等等,並且會把返回錯誤的請求重新提交到另一個節點;
6、Nginx不僅僅是一款優秀的負載均衡器/反向代理軟件,它同時也是功能強大的Web應用服務器。LNMP現在也是非常流行的web環境,大有和LAMP環境分庭抗禮之勢,Nginx在處理靜態頁面、特別是抗高併發方面相對apache有優勢;
7、Nginx現在作爲Web反向加速緩存越來越成熟了,速度比傳統的Squid服務器更快,有需求的朋友可以考慮用其作爲反向代理加速器;
Nginx的缺點:
1、Nginx不支持url來檢測。
2、Nginx僅能支持http和Email,這個它的弱勢。
3、Nginx的Session的保持,Cookie的引導能力相對欠缺。

HAProxy的優點:
1、HAProxy是支持虛擬主機的,可以工作在4、7層(支持多網段);
2、能夠補充Nginx的一些缺點比如Session的保持,Cookie的引導等工作;
3、支持url檢測後端的服務器;
4、它跟LVS一樣,本身僅僅就只是一款負載均衡軟件;單純從效率上來講HAProxy更會比Nginx有更出色的負載均衡速度,在併發處理上也是優於Nginx的;
5、HAProxy可以對Mysql讀進行負載均衡,對後端的MySQL節點進行檢測和負載均衡,不過在後端的MySQL slaves數量超過10臺時性能不如LVS;
6、HAProxy的算法較多,達到8種;

負載均衡的基礎技術
1、http重定向。HTTP重定向就是應用層的請求轉發,用戶的請求到了HTTP重定向負載均衡服務器,根據算法要求用戶重定向,瀏覽器自動重新請求實際服務器的IP地址。
優點:簡單
缺點:性能較差

2、DNS域名解析負載均衡。DNS域名解析負載均衡就是在用戶請求DNS服務器,獲取域名對應的IP地址時,DNS服務器直接解析到負載均衡後的服務器IP。
優點:使用DNS省心,不用我們去維護。
缺點:使用DNS,它不具備故障檢測功能,DNS解析結果會被緩存因此效果一般,DNS負載均衡多數爲商業產品,其功能、管理權限有限。

3、反向代理服務器。反向代理服務器轉發的請求在HTTP協議層面,因此也叫應用層負載均衡。用戶的請求到達反向代理服務器,由反向代理服務器根據算法轉發到具體的服務器。反向代理軟件常用的有apache、nginx。
優點:部署簡單。
缺點:反向代理服務器是所有請求和響應的分發服務器,其性能可能會成爲瓶頸。特別是上傳大文件。

4、IP層負載均衡。用戶的請求到達負載均衡器後,通過修改請求的目的IP地址,實現負載均衡。代表實現LVS的NAT模式
優點:性能更好。
缺點:負載均衡器的寬帶成爲瓶頸。

5、數據鏈路層負載均衡。用戶的請求到達負載均衡器後,通過修改請求的mac地址,實現負載均衡。與IP負載均衡不同當請求訪問完服務器之後,直接返回客戶而無需再經過負載均衡器。代表實現LVS的DR模式

常見的調度算法:摘自(互聯網)
1、rr 輪詢調度算法。顧名思義,輪詢分發請求。
優點:實現簡單
缺點:不考慮每臺服務器的處理能力

2、wrr 加權調度算法。我們給每個服務器設置權值weight,負載均衡調度器根據權值調度服務器,服務器被調用的次數跟權值成正比。
優點:考慮了服務器處理能力的不同

3、sh 原地址散列:提取用戶IP,根據散列函數得出一個key,再根據靜態映射表,查處對應的value,即目標服務器IP。過目標機器超負荷,則返回空。

4、dh 目標地址散列:同上,只是現在提取的是目標地址的IP來做哈希。
優點:以上兩種算法的都能實現同一個用戶訪問同一個服務器。

5、lc 最少連接。優先把請求轉發給連接數少的服務器。
優點:使得集羣中各個服務器的負載更加均勻。

6、wlc 加權最少連接。在lc的基礎上,爲每臺服務器加上權值。算法爲:(活動連接數*256+非活動連接數)÷權重 ,計算出來的值小的服務器優先被選擇。
優點:可以根據服務器的能力分配請求。

7、sed 最短期望延遲。其實sed跟wlc類似,區別是不考慮非活動連接數。算法爲:(活動連接數+1)*256÷權重,同樣計算出來的值小的服務器優先被選擇。

8、nq 永不排隊。改進的sed算法。我們想一下什麼情況下才能“永不排隊”,那就是服務器的連接數爲0的時候,那麼假如有服務器連接數爲0,均衡器直接把請求轉發給它,無需經過sed的計算。

9、LBLC 基於局部性的最少連接。均衡器根據請求的目的IP地址,找出該IP地址最近被使用的服務器,把請求轉發之,若該服務器超載,最採用最少連接數算法。

10、LBLCR 帶複製的基於局部性的最少連接。均衡器根據請求的目的IP地址,找出該IP地址最近使用的“服務器組”,注意,並不是具體某個服務器,然後採用最少連接數從該組中挑出具體的某臺服務器出來,把請求轉發之。若該服務器超載,那麼根據最少連接數算法,在集羣的非本服務器組的服務器中,找出一臺服務器出來,加入本服務器組,然後把請求轉發之。

session會話保持
session sticky
ip based
cookie based
session replication
session server

1、Session Sticky。始終將同一個請求者的連接定向至同一個RS(第一次請求時仍由調度方法選擇);沒有容錯能力,有損均衡效果。常見的算法有ip_hash法,即上面提到的兩種散列算法。
優點:實現簡單。
缺點:無高可用,反均衡。

2、Session Replication。在RS之間同步session,因此每個RS持集羣中所有的session;對於大規模集羣環境不適用。
優點:減輕負載均衡服務器的壓力,可以隨意調度。
缺點:帶寬、內存佔用量大,併發能力有限。

3、Session Server:利用單獨部署的服務器來統一管理session; 實現了session和應用服務器的解耦。
優點:相比session replication的方案,集羣間對於寬帶和內存的壓力減少了很多。
缺點:需要維護存儲session的數據庫。

4、Cookie Base:cookie base就是把session存在cookie中,由瀏覽器來告訴應用服務器用戶的session是什麼,同樣實現了session和應用服務器的解耦。
優點:實現簡單,基本免維護。
缺點:cookie長度限制,安全性低,寬帶消耗。

應用從資源佔用的角度分類
1、CPU Bound 【CPU密集型】一般指aap server
2、IO Bound 【IO密集型】一般指db server

有了以上理論經驗,根據業務我們可以重新對架構演進爲以下方案:
大型網站架構演變

2.4. 第四階段【數據庫讀寫分離】

前面幾個階段我們都是假設後端數據庫負載沒問題,但隨着訪問量的增大,數據庫的負載也在慢慢增高。那麼可能有人馬上想到跟應用服務器一樣,把數據庫一分爲二再負載均衡即可。但對於數據庫來說,並沒有那麼簡單。假如我們簡單的把數據庫一分爲二,然後對於數據庫的請求,分別負載到A機器和B機器,那麼顯然會造成兩臺數據庫數據不一致的問題。那麼對於這種情況,我們可以先考慮使用讀寫分離的方式。
大型網站架構演變

需要注意:引用MySQL主從勢必會面臨的問題,數據複製的問題、應用選擇數據源的問題
解決方案:使用MySQL自帶的master+slave的方式實現主從複製。採用第三方數據庫中間件,例如mycat。mycat是從cobar發展而來的。mycat目前是國內比較好的mysql開源數據庫分庫分表中間件。

2.5. 第五階段【引入搜索引擎實現全文搜索】

MySQL對於全局搜索能力支持不強,MySQL只對MyISAM引擎做全文索引但不支持事務,而MySQL對InnoDB引擎不支持全文索引。當一個站點到了這一個階段其用戶搜索量是非常大的。做爲一個電商站點的交易達成有70%是通過搜索進行的,由此像這種越來越多的搜索需求使得我們數據庫根本就沒辦法應付這種需要,因爲每一次搜索都是一次全面查詢,常常對模糊查找力不從心,即使做了讀寫分離,這個問題還未能解決。我們要想應付這種需求,一般只能自己構建搜索引擎來緩解讀庫的壓力。

搜索引擎並不能替代數據庫,他解決了某些場景下的“讀”的問題,是否引入搜索引擎,需要綜合考慮整個系統的需求。引入搜索引擎後的系統結構:
大型網站架構演變

2.6. 第六階段【引入緩存】

1、頁面緩存
web服務器壓力較大時,如果讓站點的一部分內容能緩存,一部分內容不能緩存,我們可以使用ESI動態緩存技術。web緩存服務器還可以對jpg、jpeg、gif、png、html、css、js格式的頁面做緩存。例如:varnish, squid

2、數據緩存
隨着訪問量的增加,逐漸出現了許多用戶訪問同一部分內容的情況,對於這些比較熱門的內容,沒必要每次都從數據庫讀取,我們可以使用緩存技術。例如:memcached, redis

優點:減輕數據庫的壓力、大幅度提高訪問速度
缺點:需要維護緩存服務器、提高了編碼的複雜性

緩存服務器集羣的調度算法不同與上面提到的應用服務器和數據庫,最好採用“一致性哈希算法”。
大型網站架構演變

2.7. 第七階段【數據庫拆分】

當訪問量逐漸增大,單一應用增加機器帶來的效果不明顯,需要考結合業務考慮數據庫拆分,來提升系統運行效率。我們的網站演進到現在,交易、商品、用戶的數據都還在同一個數據庫中。儘管採取了增加緩存,讀寫分離的方式,但隨着數據庫的壓力繼續增加,數據庫的瓶頸越來越突出,此時主庫寫操作壓力只能做數據庫拆分,我們可以有垂直拆分和水平拆分兩種選擇。

1、垂直拆分:把數據庫中不同的業務的數據拆分到不同的數據庫服務器中。
大型網站架構演變

2、水平拆分:把一個單獨的表中的數據拆分到多個不同的數據庫服務器上。
大型網站架構演變

2.8. 第八階段【應用拆分】

隨着業務的發展,業務越來越多,應用越來越大。我們需要考慮如何避免讓應用越來越臃腫。這就需要把應用拆開,從一個應用變爲倆個甚至更多。還是以我們上面的例子,我們可以把用戶、商品、交易拆分開。變成“用戶、商品”和“用戶,交易”兩個子系統。
大型網站架構演變

需要注意:這樣拆分後,可能會有一些相同的代碼,如用戶相關的代碼,商品和交易都需要用戶信息,所以在兩個系統中都保留差不多的操作用戶信息的代碼。如何保證這些代碼可以複用是一個需要解決的問題。
解決方案:通過走服務化的路線來解決,把公共的服務拆分出來,形成一種服務化的模式,簡稱SOA。

服務化之後的系統結構:
大型網站架構演變

需要注意:如何進行遠程的服務調用
解決方案:我們可以通過引入消息中間件來解決

2.9. 第九階段【引入消息中間件】

隨着網站的繼續發展,我們的系統中可能出現不同語言開發的子模塊和部署在不同平臺的子系統。此時我們需要一個平臺來傳遞可靠的,與平臺和語言無關的數據,並且能夠把負載均衡透明化,能在調用過程中收集調用數據並分析之,推測出網站的訪問增長率等等一系列需求,對於網站應該如何成長做出預測。開源消息中間件有阿里的dubbo,可以搭配Google開源的分佈式程序協調服務zookeeper實現服務器的註冊與發現。

引入消息中間件後的結構:
大型網站架構演變

3、高性能設計

三層架構(3-tier architecture) 通常意義上的三層架構就是將整個業務應用劃分爲:界面層(User Interface layer)、業務邏輯層(Business Logic Layer)、數據訪問層(Data access layer)。區分層次的目的即爲了“高內聚低耦合”的思想。在軟件體系架構設計中,分層式結構是最常見,也是最重要的一種結構。微軟推薦的分層式結構一般分爲三層,從下至上分別爲:數據訪問層、業務邏輯層(又或稱爲領域層)、表示層。(百度百科)

大型網站架構演變
大型網站架構演變

大型網站架構演變

微服務的特點:
單一職責:微服務中每一個服務都對應唯一的業務能力,做到單一職責。
微:微服務的服務拆分粒度很小,例如一個用戶管理就可以作爲一個服務。每個服務雖小,但“五臟俱全”。
面向服務:面向服務是說每個服務都要對外暴露服務接口API。並不關心服務的技術實現,做到與平臺和語言無關,也不限定用什麼技術實現,只要提供Rest的接口即可。
自治:自治是說服務間互相獨立,互不干擾
團隊獨立:每個服務都是一個獨立的開發團隊,人數不能過多。
技術獨立:因爲是面向服務,提供Rest接口,使用什麼技術沒有別人干涉
前後端分離:採用前後端分離開發,提供統一Rest接口,後端不用再爲PC、移動段開發不同接口
數據庫分離:每個服務都使用自己的數據源
部署獨立,服務間雖然有調用,但要做到服務重啓不影響其它服務。有利於持續集成和持續交付。每個服務都是獨立的組件,可複用,可替換,降低耦合,易維護。
大型網站架構演變
大型網站架構演變

架構優化:
• 以用戶爲中心,提供快速的網頁訪問體驗。主要參數有較短的響應時間,較大的併發處理能力,較高的吞吐量,穩定的性能參數;
• 可分爲前端優化,應用層優化,代碼層優化,存儲層優化;
• 前端優化:網站業務邏輯之前的部分;
• 瀏覽器優化:減少Http請求數,使用瀏覽器緩存,啓用壓縮,Css Js位置,Js異步,減少Cookie傳輸;
• CDN加速,反向代理;
• 應用層優化:處理網站業務的服務器。使用緩存,異步,集羣;
• 代碼優化:合理的架構,多線程,資源複用(對象池,線程池等),良好的數據結構,JVM調優,單例,Cache等;
• 存儲優化:緩存,固態硬盤,光纖傳輸,優化讀寫,磁盤冗餘,分佈式存儲(HDFS),NOSQL等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章