大型網站架構的演進最開始都是由小及大慢慢演變過來的,任何一個好的架構都不是設計出來的,是通過業務發展迭代而來的,這個觀點我是贊同的。對於網站架構技術很是有興趣,一直持續關注學習架構技術,本次想經過大型網站技術發展歷程,剖析大型網站技術架構模式,深刻分析大型互聯網架構設計。這篇文章咱們只關注架構的演變歷程。
經過電商業務爲例,該系統的功能有用戶模塊【用戶註冊和管理】、商品模塊【商品展現和管理】、交易模塊【建立交易和管理】。經過圖例分析一個最初從單臺LAMP怎麼發展到龐大的分佈架構體系。css
線上系統高可用參考指標:
html
網站程序用到的開源框架如maven+spring+struct+hibernate、maven+spring+springmvc+mybatis;網站初期,咱們常常會用單機跑全部的程序和軟件。一般由app server 和DB server組成,如tomcat和mysq;最後經過JDBC進行數據庫的鏈接和操做。
前端
通常5萬pv到30萬pv訪問量,結合內核參數調優、web應用性能參數調優、數據庫調優,基本上可以穩定的運行。mysql
隨着網站的發展當訪問量逐漸增大,服務器的負載慢慢提升,系統的壓力愈來愈大,響應速度愈來愈慢,這個時候比較明顯的是數據庫和應用互相影響,應用出問題了,數據庫也很容易出現問題,而數據庫出問題的時候,應用也容易出問題。在服務器尚未超載的時候,咱們應該提早作好準備,提高網站的負載能力。假如咱們代碼層面已難以優化,在不提升單臺機器的性能的狀況下,將應用和數據庫從物理上分離,增長機器是一個不錯的方式,不只能夠有效地提升系統的負載能力,並且性價比高。此時咱們能夠把數據庫、web服務器拆分開來,這樣不只提升了單臺機器的負載能力,也提升了容災能力。
nginx
隨着用戶量的增大、對帶寬需求的增大、對CPU處理能力的增大;不足以融合全部用戶的需求了,或者網站業務量的需求了。此處不多也不該該直接就對它作負載均衡式的擴展,由於數據同步很麻。因此咱們架構擴展,不會上來就直接作負載均衡式的每一組組件當作一個總體來進行擴展,而是功能上切割 。這個時候技術上沒有什麼新的要求,但你發現確實起到效果了,系統又恢復到之前的響應速度了,而且支撐住了更高的流量,而且不會由於數據庫和應用造成互相的影響。web
隨着訪問量繼續增長,單臺應用服務器已經沒法知足需求了。假設數據庫服務器沒有壓力,咱們能夠把應用服務器從一臺變成了兩臺甚至多臺,把用戶的請求分散到不一樣的服務器中,從而提升負載能力。此時咱們應該選擇一款合適的負載均衡產品,通常來說keepalived配合上ipvsadm作負載均衡,可謂是神器。這一階段是須要掌握更多基礎知識的關鍵節點。如下可使用DNS解析對用戶請求作負載均衡:
redis
須要注意:負載均衡產品的選擇、負載均衡算法的選擇、用戶session保持的問題、應用佔用資源的角度選擇合理的服務器配置。
解決方案:根據如下技術特性選擇適合業務的產品、技術。例如nginx+keepalived一臺服務器、apache+tomcat一臺服務器、mysql一臺服務器。算法
三種負載均衡器的優缺點說明以下:摘自(互聯網)
LVS的優勢:
一、抗負載能力強、工做在第4層僅做分發之用,沒有流量的產生,這個特色也決定了它在負載均衡軟件裏的性能最強的;無流量,同時保證了均衡器IO的性能不會受到大流量的影響;
二、工做穩定,自身有完整的雙機熱備方案,如LVS+Keepalived和LVS+Heartbeat;
三、應用範圍比較廣,能夠對全部應用作負載均衡;
四、配置性比較低,這是一個缺點也是一個優勢,由於沒有可太多配置的東西,因此並不須要太多接觸,大大減小了人爲出錯的概率;
LVS的缺點:
一、軟件自己不支持正則處理,不能作動靜分離,這就凸顯了Nginx/HAProxy+Keepalived的優點。
二、若是網站應用比較龐大,LVS/DR+Keepalived就比較複雜了,特別是後面有Windows Server應用的機器,實施及配置還有維護過程就比較麻煩,相對而言,Nginx/HAProxy+Keepalived就簡單多了。spring
Nginx的優勢:
一、工做在OSI第7層,能夠針對http應用作一些分流的策略。好比針對域名、目錄結構。它的正則比HAProxy更爲強大和靈活;
二、Nginx對網絡的依賴很是小,理論上能ping通就就能進行負載功能,這個也是它的優點所在;
三、Nginx安裝和配置比較簡單,測試起來比較方便;
四、能夠承擔高的負載壓力且穩定,通常能支撐超過幾萬次的併發量;
五、Nginx能夠經過端口檢測到服務器內部的故障,好比根據服務器處理網頁返回的狀態碼、超時等等,而且會把返回錯誤的請求從新提交到另外一個節點;
六、Nginx不只僅是一款優秀的負載均衡器/反向代理軟件,它同時也是功能強大的Web應用服務器。LNMP如今也是很是流行的web環境,大有和LAMP環境平起平坐之勢,Nginx在處理靜態頁面、特別是抗高併發方面相對apache有優點;
七、Nginx如今做爲Web反向加速緩存愈來愈成熟了,速度比傳統的Squid服務器更快,有需求的朋友能夠考慮用其做爲反向代理加速器;
Nginx的缺點:
一、Nginx不支持url來檢測。
二、Nginx僅能支持http和Email,這個它的弱勢。
三、Nginx的Session的保持,Cookie的引導能力相對欠缺。sql
HAProxy的優勢:
一、HAProxy是支持虛擬主機的,能夠工做在四、7層(支持多網段);
二、可以補充Nginx的一些缺點好比Session的保持,Cookie的引導等工做;
三、支持url檢測後端的服務器;
四、它跟LVS同樣,自己僅僅就只是一款負載均衡軟件;單純從效率上來說HAProxy更會比Nginx有更出色的負載均衡速度,在併發處理上也是優於Nginx的;
五、HAProxy能夠對Mysql讀進行負載均衡,對後端的MySQL節點進行檢測和負載均衡,不過在後端的MySQL slaves數量超過10臺時性能不如LVS;
六、HAProxy的算法較多,達到8種;
負載均衡的基礎技術:
一、http重定向。HTTP重定向就是應用層的請求轉發,用戶的請求到了HTTP重定向負載均衡服務器,根據算法要求用戶重定向,瀏覽器自動從新請求實際服務器的IP地址。
優勢:簡單
缺點:性能較差
二、DNS域名解析負載均衡。DNS域名解析負載均衡就是在用戶請求DNS服務器,獲取域名對應的IP地址時,DNS服務器直接解析到負載均衡後的服務器IP。
優勢:使用DNS省心,不用咱們去維護。
缺點:使用DNS,它不具有故障檢測功能,DNS解析結果會被緩存所以效果通常,DNS負載均衡多數爲商業產品,其功能、管理權限有限。
三、反向代理服務器。反向代理服務器轉發的請求在HTTP協議層面,所以也叫應用層負載均衡。用戶的請求到達反向代理服務器,由反向代理服務器根據算法轉發到具體的服務器。反向代理軟件經常使用的有apache、nginx。
優勢:部署簡單。
缺點:反向代理服務器是全部請求和響應的分發服務器,其性能可能會成爲瓶頸。特別是上傳大文件。
四、IP層負載均衡。用戶的請求到達負載均衡器後,經過修改請求的目的IP地址,實現負載均衡。表明實現LVS的NAT模式
優勢:性能更好。
缺點:負載均衡器的寬帶成爲瓶頸。
五、數據鏈路層負載均衡。用戶的請求到達負載均衡器後,經過修改請求的mac地址,實現負載均衡。與IP負載均衡不一樣當請求訪問完服務器以後,直接返回客戶而無需再通過負載均衡器。表明實現LVS的DR模式
常見的調度算法:摘自(互聯網)
一、rr 輪詢調度算法。顧名思義,輪詢分發請求。
優勢:實現簡單
缺點:不考慮每臺服務器的處理能力
二、wrr 加權調度算法。咱們給每一個服務器設置權值weight,負載均衡調度器根據權值調度服務器,服務器被調用的次數跟權值成正比。
優勢:考慮了服務器處理能力的不一樣
三、sh 原地址散列:提取用戶IP,根據散列函數得出一個key,再根據靜態映射表,查處對應的value,即目標服務器IP。過目標機器超負荷,則返回空。
四、dh 目標地址散列:同上,只是如今提取的是目標地址的IP來作哈希。
優勢:以上兩種算法的都能實現同一個用戶訪問同一個服務器。
五、lc 最少鏈接。優先把請求轉發給鏈接數少的服務器。
優勢:使得集羣中各個服務器的負載更加均勻。
六、wlc 加權最少鏈接。在lc的基礎上,爲每臺服務器加上權值。算法爲:(活動鏈接數*256+非活動鏈接數)÷權重 ,計算出來的值小的服務器優先被選擇。
優勢:能夠根據服務器的能力分配請求。
七、sed 最短時間望延遲。其實sed跟wlc相似,區別是不考慮非活動鏈接數。算法爲:(活動鏈接數+1)*256÷權重,一樣計算出來的值小的服務器優先被選擇。
八、nq 永不排隊。改進的sed算法。咱們想一下什麼狀況下才能「永不排隊」,那就是服務器的鏈接數爲0的時候,那麼假若有服務器鏈接數爲0,均衡器直接把請求轉發給它,無需通過sed的計算。
九、LBLC 基於局部性的最少鏈接。均衡器根據請求的目的IP地址,找出該IP地址最近被使用的服務器,把請求轉發之,若該服務器超載,最採用最少鏈接數算法。
十、LBLCR 帶複製的基於局部性的最少鏈接。均衡器根據請求的目的IP地址,找出該IP地址最近使用的「服務器組」,注意,並非具體某個服務器,而後採用最少鏈接數從該組中挑出具體的某臺服務器出來,把請求轉發之。若該服務器超載,那麼根據最少鏈接數算法,在集羣的非本服務器組的服務器中,找出一臺服務器出來,加入本服務器組,而後把請求轉發之。
session會話保持:
session sticky
ip based
cookie based
session replication
session server
一、Session Sticky。始終將同一個請求者的鏈接定向至同一個RS(第一次請求時仍由調度方法選擇);沒有容錯能力,有損均衡效果。常見的算法有ip_hash法,即上面提到的兩種散列算法。
優勢:實現簡單。
缺點:無高可用,反均衡。
二、Session Replication。在RS之間同步session,所以每一個RS持集羣中全部的session;對於大規模集羣環境不適用。
優勢:減輕負載均衡服務器的壓力,能夠隨意調度。
缺點:帶寬、內存佔用量大,併發能力有限。
三、Session Server:利用單獨部署的服務器來統一管理session; 實現了session和應用服務器的解耦。
優勢:相比session replication的方案,集羣間對於寬帶和內存的壓力減小了不少。
缺點:須要維護存儲session的數據庫。
四、Cookie Base:cookie base就是把session存在cookie中,由瀏覽器來告訴應用服務器用戶的session是什麼,一樣實現了session和應用服務器的解耦。
優勢:實現簡單,基本免維護。
缺點:cookie長度限制,安全性低,寬帶消耗。
應用從資源佔用的角度分類:
一、CPU Bound 【CPU密集型】通常指aap server
二、IO Bound 【IO密集型】通常指db server
有了以上理論經驗,根據業務咱們能夠從新對架構演進爲如下方案:
前面幾個階段咱們都是假設後端數據庫負載沒問題,但隨着訪問量的增大,數據庫的負載也在慢慢增高。那麼可能有人立刻想到跟應用服務器同樣,把數據庫一分爲二再負載均衡便可。但對於數據庫來講,並無那麼簡單。假如咱們簡單的把數據庫一分爲二,而後對於數據庫的請求,分別負載到A機器和B機器,那麼顯然會形成兩臺數據庫數據不一致的問題。那麼對於這種狀況,咱們能夠先考慮使用讀寫分離的方式。
須要注意:引用MySQL主從勢必會面臨的問題,數據複製的問題、應用選擇數據源的問題
解決方案:使用MySQL自帶的master+slave的方式實現主從複製。採用第三方數據庫中間件,例如mycat。mycat是從cobar發展而來的。mycat目前是國內比較好的mysql開源數據庫分庫分表中間件。
MySQL對於全局搜索能力支持不強,MySQL只對MyISAM引擎作全文索引但不支持事務,而MySQL對InnoDB引擎不支持全文索引。當一個站點到了這一個階段其用戶搜索量是很是大的。作爲一個電商站點的交易達成有70%是經過搜索進行的,由此像這種愈來愈多的搜索需求使得咱們數據庫根本就沒辦法應付這種須要,由於每一次搜索都是一次全面查詢,經常對模糊查找力不從心,即便作了讀寫分離,這個問題還未能解決。咱們要想應付這種需求,通常只能本身構建搜索引擎來緩解讀庫的壓力。
搜索引擎並不能替代數據庫,他解決了某些場景下的「讀」的問題,是否引入搜索引擎,須要綜合考慮整個系統的需求。引入搜索引擎後的系統結構:
一、頁面緩存
web服務器壓力較大時,若是讓站點的一部份內容能緩存,一部份內容不能緩存,咱們可使用ESI動態緩存技術。web緩存服務器還能夠對jpg、jpeg、gif、png、html、css、js格式的頁面作緩存。例如:varnish, squid
二、數據緩存
隨着訪問量的增長,逐漸出現了許多用戶訪問同一部份內容的狀況,對於這些比較熱門的內容,不必每次都從數據庫讀取,咱們可使用緩存技術。例如:memcached, redis
優勢:減輕數據庫的壓力、大幅度提升訪問速度
缺點:須要維護緩存服務器、提升了編碼的複雜性
緩存服務器集羣的調度算法不一樣與上面提到的應用服務器和數據庫,最好採用「一致性哈希算法」。
當訪問量逐漸增大,單一應用增長機器帶來的效果不明顯,須要考結合業務考慮數據庫拆分,來提高系統運行效率。咱們的網站演進到如今,交易、商品、用戶的數據都還在同一個數據庫中。儘管採起了增長緩存,讀寫分離的方式,但隨着數據庫的壓力繼續增長,數據庫的瓶頸愈來愈突出,此時主庫寫操做壓力只能作數據庫拆分,咱們能夠有垂直拆分和水平拆分兩種選擇。
一、垂直拆分:把數據庫中不一樣的業務的數據拆分到不一樣的數據庫服務器中。
二、水平拆分:把一個單獨的表中的數據拆分到多個不一樣的數據庫服務器上。
隨着業務的發展,業務愈來愈多,應用愈來愈大。咱們須要考慮如何避免讓應用愈來愈臃腫。這就須要把應用拆開,從一個應用變爲倆個甚至更多。仍是以咱們上面的例子,咱們能夠把用戶、商品、交易拆分開。變成「用戶、商品」和「用戶,交易」兩個子系統。
須要注意:這樣拆分後,可能會有一些相同的代碼,如用戶相關的代碼,商品和交易都須要用戶信息,因此在兩個系統中都保留差很少的操做用戶信息的代碼。如何保證這些代碼能夠複用是一個須要解決的問題。
解決方案:經過走服務化的路線來解決,把公共的服務拆分出來,造成一種服務化的模式,簡稱SOA。
服務化以後的系統結構:
須要注意:如何進行遠程的服務調用
解決方案:咱們能夠經過引入消息中間件來解決
隨着網站的繼續發展,咱們的系統中可能出現不一樣語言開發的子模塊和部署在不一樣平臺的子系統。此時咱們須要一個平臺來傳遞可靠的,與平臺和語言無關的數據,而且可以把負載均衡透明化,能在調用過程當中收集調用數據並分析之,推測出網站的訪問增加率等等一系列需求,對於網站應該如何成長作出預測。開源消息中間件有阿里的dubbo,能夠搭配Google開源的分佈式程序協調服務zookeeper實現服務器的註冊與發現。
引入消息中間件後的結構:
三層架構(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等。