動態應用,是相對於網站靜態內容而言,是指以c/c++、php、Java、perl、.net等服務器端語言開發的網絡應用軟件,好比論壇、網絡相冊、交友、BLOG等常見應用。動態應用系統一般與數據庫系統、緩存系統、分佈式存儲系統等密不可分。php
大型動態應用系統平臺主要是針對於大流量、高併發網站創建的底層系統架構。大型網站的運行須要一個可靠、安全、可擴展、易維護的應用系統平臺作爲支撐,以保證網站應用的平穩運行。css
大型動態應用系統又可分爲幾個子系統:html
1)Web前端系統前端
2)負載均衡系統java
3)數據庫集羣系統mysql
4)緩存系統linux
5)分佈式存儲系統nginx
6)分佈式服務器管理系統c++
7)代碼分發系統web
結構圖:
爲了達到不一樣應用的服務器共享、避免單點故障、集中管理、統一配置等目的,不以應用劃分服務器,而是將全部服務器作統一使用,每臺服務器均可以對多個應用提供服務,當某些應用訪問量升高時,經過增長服務器節點達到整個服務器集羣的性能提升,同時使他應用也會受益。該Web前端系統基於Apache/Lighttpd/Eginx等的虛擬主機平臺,提供PHP程序運行環境。服務器對開發人員是透明的,不須要開發人員介入服務器管理
負載均衡系統分爲硬件和軟件兩種。硬件負載均衡效率高,可是價格貴,好比F5等。軟件負載均衡系統價格較低或者免費,效率較硬件負載均衡系統低,不過對於流量通常或稍大些網站來說也足夠使用,好比lvs, nginx。大多數網站都是硬件、軟件負載均衡系統並用。
結構圖:
因爲Web前端採用了負載均衡集羣結構提升了服務的有效性和擴展性,所以數據庫必須也是高可靠的,才能保證整個服務體系的高可靠性,如何構建一個高可靠的、能夠提供大規模併發處理的數據庫體系?
咱們能夠採用如上圖所示的方案:
1) 使用 MySQL 數據庫,考慮到Web應用的數據庫讀多寫少的特色,咱們主要對讀數據庫作了優化,提供專用的讀數據庫和寫數據庫,在應用程序中實現讀操做和寫操做分別訪問不一樣的數據庫。
2) 使用 MySQL Replication 機制實現快速將主庫(寫庫)的數據庫複製到從庫(讀庫)。一個主庫對應多個從庫,主庫數據實時同步到從庫。
3) 寫數據庫有多臺,每臺均可以提供多個應用共同使用,這樣能夠解決寫庫的性能瓶頸問題和單點故障問題。
4) 讀數據庫有多臺,經過負載均衡設備實現負載均衡,從而達到讀數據庫的高性能、高可靠和高可擴展性。
5) 數據庫服務器和應用服務器分離。
6) 從數據庫使用BigIP作負載均衡。
緩存分爲文件緩存、內存緩存、數據庫緩存。在大型Web應用中使用最多且效率最高的是內存緩存。最經常使用的內存緩存工具是Memcached。使用正確的緩存系統能夠達到實現如下目標:
一、使用緩存系統能夠提升訪問效率,提升服務器吞吐能力,改善用戶體驗。
二、減輕對數據庫及存儲集服務器的訪問壓力。
三、Memcached服務器有多臺,避免單點故障,提供高可靠性和可擴展性,提升性能。
結構圖:
Web系統平臺中的存儲需求有下面兩個特色:
1) 存儲量很大,常常會達到單臺服務器沒法提供的規模,好比相冊、視頻等應用。所以須要專業的大規模存儲系統。
2) 負載均衡cluster中的每一個節點都有可能訪問任何一個數據對象,每一個節點對數據的處理也能被其餘節點共享,所以這些節點要操做的數據從邏輯上看只能是一個總體,不是各自獨立的數據資源。
所以高性能的分佈式存儲系統對於大型網站應用來講是很是重要的一環。(這個地方須要加入對某個分佈式存儲系統的簡單介紹。)
結構圖:
隨着網站訪問流量的不斷增長,大多的網絡服務都是以負載均衡集羣的方式對外提供服務,隨之集羣規模的擴大,原來基於單機的服務器管理模式已經不可以知足咱們的需求,新的需求必須可以集中式的、分組的、批量的、自動化的對服務器進行管理,可以批量化的執行計劃任務。
在分佈式服務器管理系統軟件中有一些比較優秀的軟件,其中比較理想的一個是Cfengine。它能夠對服務器進行分組,不一樣的分組能夠分別定製系統配置文件、計劃任務等配置。它是基於C/S 結構的,全部的服務器配置和管理腳本程序都保存在Cfengine Server上,而被管理的服務器運行着 Cfengine Client 程序,Cfengine Client經過SSL加密的鏈接按期的向服務器端發送請求以獲取最新的配置文件和管理命令、腳本程序、補丁安裝等任務。
有了Cfengine這種集中式的服務器管理工具,咱們就能夠高效的實現大規模的服務器集羣管理,被管理服務器和 Cfengine Server 能夠分佈在任何位置,只要網絡能夠連通就能實現快速自動化的管理。
結構圖:
隨着網站訪問流量的不斷增長,大多的網絡服務都是以負載均衡集羣的方式對外提供服務,隨之集羣規模的擴大,爲了知足集羣環境下程序代碼的批量分發和更新,咱們還須要一個程序代碼發佈系統。
這個發佈系統能夠幫咱們實現下面的目標:
1) 生產環境的服務器以虛擬主機方式提供服務,不須要開發人員介入維護和直接操做,提供發佈系統能夠實現不須要登錄服務器就能把程序分發到目標服務器。
2) 咱們要實現內部開發、內部測試、生產環境測試、生產環境發佈的4個開發階段的管理,發佈系統能夠介入各個階段的代碼發佈。
3) 咱們須要實現源代碼管理和版本控制,SVN能夠實現該需求。
這裏面可使用經常使用的工具Rsync,經過開發相應的腳本工具實現服務器集羣間代碼同步分發。
主體架構能夠基於 Struts 1.X/2.X,固然有不少更好的控制層框架供選擇,以快速敏捷爲準則吧。
抽象出核心庫封裝 控制器和中間層的操做。
在大規模集羣環境下,session複製會引發嚴重的性能問題。考慮用 集羣緩存 + cookie驗證 代替session實現權限控制吧。
二、Cache層
配置 Memcache 組成集羣緩存
對 Memcache 客戶端進行封裝
Memcached 節點組成池,調用示意:opList (BizName, 策略 ...)
三、中間層
「中間層」能夠理解爲基於應用和數據之間的層次。它被設計用來爲Web應用提供:數據緩存 和 對應用透明的數據訪問——即應用不須要考慮數據表拆分的問題。以服務的方式提供對存儲層的高性能調用以及分佈式計算。可供選擇的框架:ICE 、Hadoop 直接基於Memcache開發(減小複雜度,推薦)
四、存儲
推薦MySQL,理由:免費,通過實踐檢驗,有大量成熟的案例、解決方案、技術支持。
小規模:一個 data table 維護存儲服務器陣列,內容 -> mount ……
大規模:Master-Slave模式+MySQL Proxy,實現數據庫讀寫分離。在中間層的包裝下,可作以下擴展,以支持更大規模的數據存取:
數據庫/表水平拆分,例 User -> User33% + User33% + User34%
數據庫/表垂直拆分,例 User -> UserBaseInfo + UserAddrInfo
也可考慮使用 LongStore (龍存) 解決方案,由龍存管理存儲陣列……
五、部署
劃分子域名,每一個子域名一個Web應用包,互不干擾
靜態資源(css, js, image ...)使用專門的靜態服務器
六、負載均衡
小規模:DNS輪詢。
大規模:F5, 2*X 臺F5服務器,F5是L4/L7層交換機,每臺至少可處理200萬鏈接(與服務器內存有關)。
Ngnix是L7層交換,LVS負載均衡也是一種方案
七、Web中間件選擇
Tomcat - 最高400併發
Apache - 最高2000併發
Ngnix - 優於Apache
採用方案:Ngnix + Resin ,理由:
Resin提供更爲快速的servlet引擎 - 選擇Resin。
gzip問題 - Resin在單獨處理gzip時存在內存溢出的隱患,所以要加一層 Ngnix。
Ngnix 能減小單獨使用Resin時的內存佔用 - Resin創建1000個鏈接使用1000個線程;加Ngnix後,透過其「異步鏈接」、「創建長鏈接」機制使Resin內存壓力大大減少。
Ngnix 針對Linux系統有性能優化措施 - 0 Copy, send file ...
所以採用:1 Ngnix + 1 Resin,一對一。
靜態服務器採用:Squid + Apache, why? because Squid has cache ability ...
新變化 - Nginx從0.7.48版本開始,支持了相似Squid的緩存功能。這個緩存是把URL及相關組合看成Key,用md5編碼哈希後保存在硬盤上,因此它能夠支持任意URL連接,同時也支持 404/301/302 這樣的非200狀態碼。雖然目前官方的Nginx Web緩存服務只能爲指定URL或狀態碼設置過時時間,不支持相似Squid的PURGE指令,手動清除指定緩存頁面,可是,經過一個第三方的Nginx 模塊,能夠清除指定URL的緩存。
Nginx的Web緩存服務主要由proxy_cache相關指令集和fastcgi_cache相關指令集構成,前者用於反向代理時,對後端內容源服務器進行緩存,後者主要用於對FastCGI的動態程序進行緩存。二者的功能基本上同樣。
最新的Nginx 0.8.31版本,proxy_cache和fastcgi_cache已經比較完善,加上第三方的ngx_cache_purge模塊(用於清除指定 URL的緩存),已經能夠徹底取代Squid。有的網站已經在生產環境使用了 Nginx 的 proxy_cache 緩存功能超過兩個月,十分穩定,速度不遜於 Squid。
大型網站,好比門戶網站。在面對大量用戶訪問、高併發請求方面,基本的解決方案集中在這樣幾個環節:使用高性能的服務器、高性能的數據庫、高效率的編程語言、還有高性能的Web容器。可是除了這幾個方面,還無法根本解決大型網站面臨的高負載和高併發問題。
上面提供的幾個解決思路在必定程度上也意味着更大的投入,而且這樣的解決思路具有瓶頸,沒有很好的擴展性,下面我從低成本、高性能和高擴張性的角度來講說個人一些經驗。
一、HTML靜態化
其實你們都知道,效率最高、消耗最小的就是純靜態化的html頁面,因此咱們儘量使咱們的網站上的頁面採用靜態頁面來實現,這個最簡單的方法其實也是最有效的方法。可是對於大量內容而且頻繁更新的網站,咱們沒法所有手動去挨個實現,因而出現了咱們常見的信息發佈系統CMS,像咱們常訪問的各個門戶站點的新聞頻道,甚至他們的其餘頻道,都是經過信息發佈系統來管理和實現的,信息發佈系統能夠實現最簡單的信息錄入自動生成靜態頁面,還能具有頻道管理、權限管理、自動抓取等功能,對於一個大型網站來講,擁有一套高效、可管理的CMS是必不可少的。
除了門戶和信息發佈類型的網站,對於交互性要求很高的社區類型網站來講,儘量的靜態化也是提升性能的必要手段,將社區內的帖子、文章進行實時的靜態化,有更新的時候再從新靜態化也是大量使用的策略,像Mop的大雜燴就是使用了這樣的策略,網易社區等也是如此。目前不少博客也都實現了靜態化,我使用的這個Blog程序WordPress尚未靜態化,因此若是面對高負載訪問,www.toplee.com必定不能承受
同時,html靜態化也是某些緩存策略使用的手段,對於系統中頻繁使用數據庫查詢可是內容更新很小的應用,能夠考慮使用html靜態化來實現,好比論壇中論壇的公用設置信息,這些信息目前的主流論壇均可以進行後臺管理而且存儲再數據庫中,這些信息其實大量被前臺程序調用,可是更新頻率很小,能夠考慮將這部份內容進行後臺更新的時候進行靜態化,這樣避免了大量的數據庫訪問請求。
在進行html靜態化的時候可使用一種折中的方法,就是前端使用動態實現,在必定的策略下進行定時靜態化和定時判斷調用,這個能實現不少靈活性的操做,我開發的檯球網站故人居(www.8zone.cn)就是使用了這樣的方法,我經過設定一些html靜態化的時間間隔來對動態網站內容進行緩存,達到分擔大部分的壓力到靜態頁面上,能夠應用於中小型網站的架構上。故人居網站的地址:http://www.8zone.cn,順便提一下,有喜歡檯球的朋友多多支持我這個免費網站:)
二、圖片服務器分離
你們知道,對於Web服務器來講,無論是Apache、IIS仍是其餘容器,圖片是最消耗資源的,因而咱們有必要將圖片與頁面進行分離,這是基本上大型網站都會採用的策略,他們都有獨立的圖片服務器,甚至不少臺圖片服務器。這樣的架構能夠下降提供頁面訪問請求的服務器系統壓力,而且能夠保證系統不會由於圖片問題而崩潰。
在應用服務器和圖片服務器上,能夠進行不一樣的配置優化,好比Apache在配置ContentType的時候能夠儘可能少支持,儘量少的LoadModule,保證更高的系統消耗和執行效率。
個人檯球網站故人居8zone.cn也使用了圖片服務器架構上的分離,目前是僅僅是架構上分離,物理上沒有分離,因爲沒有錢買更多的服務器:),你們能夠看到故人居上的圖片鏈接都是相似img.9tmd.com或者img1.9tmd.com的URL。
另外,在處理靜態頁面或者圖片、js等訪問方面,能夠考慮使用lighttpd代替Apache,它提供了更輕量級和更高效的處理能力。
三、數據庫集羣和庫表散列
大型網站都有複雜的應用,這些應用必須使用數據庫,那麼在面對大量訪問的時候,數據庫的瓶頸很快就能顯現出來,這時一臺數據庫將很快沒法知足應用,因而咱們須要使用數據庫集羣或者庫表散列。
在數據庫集羣方面,不少數據庫都有本身的解決方案,Oracle、Sybase等都有很好的方案,經常使用的MySQL提供的Master/Slave也是相似的方案,您使用了什麼樣的DB,就參考相應的解決方案來實施便可。
上面提到的數據庫集羣因爲在架構、成本、擴張性方面都會受到所採用DB類型的限制,因而咱們須要從應用程序的角度來考慮改善系統架構,庫表散列是經常使用而且最有效的解決方案。咱們在應用程序中安裝業務和應用或者功能模塊將數據庫進行分離,不一樣的模塊對應不一樣的數據庫或者表,再按照必定的策略對某個頁面或者功能進行更小的數據庫散列,好比用戶表,按照用戶ID進行表散列,這樣就可以低成本的提高系統的性能而且有很好的擴展性。sohu的論壇就是採用了這樣的架構,將論壇的用戶、設置、帖子等信息進行數據庫分離,而後對帖子、用戶按照板塊和ID進行散列數據庫和表,最終能夠在配置文件中進行簡單的配置便能讓系統隨時增長一臺低成本的數據庫進來補充系統性能。
四、緩存
緩存一詞搞技術的都接觸過,不少地方用到緩存。網站架構和網站開發中的緩存也是很是重要。這裏先講述最基本的兩種緩存。高級和分佈式的緩存在後面講述。
架構方面的緩存,對Apache比較熟悉的人都能知道Apache提供了本身的mod_proxy緩存模塊,也可使用外加的Squid進行緩存,這兩種方式都可以有效的提升Apache的訪問響應能力。
網站程序開發方面的緩存,Linux上提供的Memcached是經常使用的緩存方案,很多web編程語言都提供memcache訪問接口,php、perl、c和java都有,能夠在web開發中使用,能夠實時或者Cron的把數據、對象等內容進行緩存,策略很是靈活。一些大型社區使用了這樣的架構。
另外,在使用web語言開發的時候,各類語言基本都有本身的緩存模塊和方法,PHP有Pear的Cache模塊和eAccelerator加速和Cache模塊,還要知名的Apc、XCache(國人開發的,支持!)php緩存模塊,Java就更多了,.net不是很熟悉,相信也確定有。
五、鏡像
鏡像是大型網站常採用的提升性能和數據安全性的方式,鏡像的技術能夠解決不一樣網絡接入商和地域帶來的用戶訪問速度差別,好比ChinaNet和EduNet之間的差別就促使了不少網站在教育網內搭建鏡像站點,數據進行定時更新或者實時更新。在鏡像的細節技術方面,這裏不闡述太深,有不少專業的現成的解決架構和產品可選。也有廉價的經過軟件實現的思路,好比Linux上的rsync等工具。
六、負載均衡
負載均衡將是大型網站解決高負荷訪問和大量併發請求採用的終極解決辦法。
負載均衡技術發展了多年,有不少專業的服務提供商和產品能夠選擇,我我的接觸過一些解決方法,其中有兩個架構能夠給你們作參考。另外有關初級的負載均衡DNS輪循和較專業的CDN架構就很少說了。
6.1 硬件四層交換
第四層交換使用第三層和第四層信息包的報頭信息,根據應用區間識別業務流,將整個區間段的業務流分配到合適的應用服務器進行處理。 第四層交換功能就象是虛IP,指向物理服務器。它傳輸的業務服從的協議多種多樣,有HTTP、FTP、NFS、Telnet或其餘協議。這些業務在物理服務器基礎上,須要複雜的載量平衡算法。在IP世界,業務類型由終端TCP或UDP端口地址來決定,在第四層交換中的應用區間則由源端和終端IP地址、TCP和UDP端口共同決定。
在硬件四層交換產品領域,有一些知名的產品能夠選擇,好比Alteon、F5等,這些產品很昂貴,可是物有所值,可以提供很是優秀的性能和很靈活的管理能力。Yahoo中國當初接近2000臺服務器使用了三四臺Alteon就搞定了。
6.2 軟件四層交換
你們知道了硬件四層交換機的原理後,基於OSI模型來實現的軟件四層交換也就應運而生,這樣的解決方案實現的原理一致,不過性能稍差。可是知足必定量的壓力仍是遊刃有餘的,有人說軟件實現方式其實更靈活,處理能力徹底看你配置的熟悉能力。
軟件四層交換咱們可使用Linux上經常使用的LVS來解決,LVS就是Linux Virtual Server,他提供了基於心跳線heartbeat的實時災難應對解決方案,提升系統的魯棒性,同時可供了靈活的虛擬VIP配置和管理功能,能夠同時知足多種應用需求,這對於分佈式的系統來講必不可少。
一個典型的使用負載均衡的策略就是,在軟件或者硬件四層交換的基礎上搭建squid集羣,這種思路在不少大型網站包括搜索引擎上被採用,這樣的架構低成本、高性能還有很強的擴張性,隨時往架構裏面增減節點都很是容易。這樣的架構我準備空了專門詳細整理一下和你們探討。
總結:
對於大型網站來講,前面提到的每一個方法可能都會被同時使用到,Michael這裏介紹得比較淺顯,具體實現過程當中不少細節還須要你們慢慢熟悉和體會,有時一個很小的squid參數或者apache參數設置,對於系統性能的影響就會很大,但願你們一塊兒討論,達到拋磚引玉之效。
好溼好溼
SQL語句要優化
索引建立有藝術
三大範式不可廢
冗餘字段難維護
查詢過多怎麼辦
緩存使用是本固
頻繁訪問不用怕
每秒數千扛得住
更新插入可延遲
消息隊列來輔助
滿天消息不亂飛
定向收集捋清楚
Java代碼執行快
阻塞瓶頸是同步
下降同步鎖優化
請求處理暢無阻
以上所有作到後
還需WebServer來分佈
Nginx好選擇
多臺Server同服務