大型門戶網(wǎng)站架構(gòu)心得
大型門戶網(wǎng)站站架構(gòu)心得之一:分
我們知道,對于一個(gè)大型網(wǎng)站來說,可伸縮性是非常重要的,怎么樣在縱向和橫向有良好的可伸縮性,就需要在做架構(gòu)設(shè)計(jì)的時(shí)候考慮到一個(gè)分的原則,我想在多個(gè)方面說一下怎么分:一、首先是橫向的分:
1.大的網(wǎng)站化解為多個(gè)小網(wǎng)站:當(dāng)我們一個(gè)網(wǎng)站有多個(gè)功能的時(shí)候,可以考慮把這個(gè)網(wǎng)站拆分成幾個(gè)小模塊,每一個(gè)模塊可以是一個(gè)網(wǎng)站,這樣的話我們到時(shí)候就可以很靈活地去把這些網(wǎng)站部署到不同的服務(wù)器上。
2.靜態(tài)動態(tài)分離:靜態(tài)文件和動態(tài)文件最好分離開成2個(gè)網(wǎng)站,我們知道靜態(tài)網(wǎng)站和動態(tài)網(wǎng)站對服務(wù)器來說壓力的側(cè)重不同,前者可能重IO后者重CPU,那么我們在選擇硬件的時(shí)候也可以有側(cè)重,而且靜態(tài)和動態(tài)內(nèi)容的緩存策略也不一樣。典型的應(yīng)用,我們一般會有獨(dú)立的文件或圖片服務(wù)器。
3.按照功能來分:比如有一個(gè)模塊是負(fù)責(zé)上傳的,上傳操作很消耗時(shí)間,如果和其它應(yīng)用混在一起的話很可能,一點(diǎn)點(diǎn)訪問就會使服務(wù)器癱瘓,這種特殊的模塊應(yīng)該分開。安全的不安全的也要分開,還需要考慮到以后SSL的購買。
4.我們不一定要全部用自己的服務(wù)器,搜索、報(bào)表可以依靠別人的服務(wù),比如google的搜索和報(bào)表服務(wù),自己做的不一定比得過別人,服務(wù)器帶寬都省了。
二、其次是縱向的分:
1.文件也相當(dāng)于數(shù)據(jù)庫,IO的流量可能比數(shù)據(jù)庫還大,這也算是縱向級別的訪問,上傳的文件圖片一定要和WEB服務(wù)器分開。當(dāng)然,數(shù)據(jù)庫和網(wǎng)站都放在一個(gè)服務(wù)器上的很少了,這是最基本的。
2.對于涉及到數(shù)據(jù)庫訪問的動態(tài)程序來說,我們可以使用一個(gè)中間層(所謂的應(yīng)用層或邏輯層)來訪問數(shù)據(jù)庫(部署在獨(dú)立的服務(wù)器上),最大的好處就是緩存和靈活性。緩存的內(nèi)存占用比較大,我們要把它和網(wǎng)站進(jìn)程分開,而且這樣做我們可以很方便的去改變一些數(shù)據(jù)訪問的策略,即使到時(shí)候數(shù)據(jù)庫有分布的話在這里可以做一個(gè)調(diào)配工作,這樣靈活性就很大了。還有好處是中間層可以做電線網(wǎng)通橋梁,可能網(wǎng)通訪問雙線再訪問電信會比網(wǎng)通直接訪問電信服務(wù)器快。
有人說我不分,我可以做負(fù)載均衡,對,是可以的,但是如果分的話,同樣的10臺機(jī)器肯定比不分10臺機(jī)器可以承受更多的訪問量,而且對硬件的需求可能不會很高,因?yàn)橹佬枰膫(gè)硬件特別好。爭取讓每一個(gè)服務(wù)期都不空閑,又都不是太忙,合理進(jìn)行組合調(diào)整和擴(kuò)充,這樣的系統(tǒng)伸縮性就高了,能根據(jù)訪問量來調(diào)整的前提就是之前有考慮到分,分的好處是靈活性、伸縮性、隔離性以及安全性。
三、對服務(wù)器來說,我們有幾點(diǎn)是要長期觀察的,任何一點(diǎn)都可能是瓶頸:
1.CPU:動態(tài)文件的解析需要比較多的CPU,CPU出現(xiàn)瓶頸就要看是不是哪個(gè)功能過長時(shí)間占用線程,如果是就分出去;蛘呔褪敲恳粋(gè)請求處理時(shí)間不長,但是訪問量很高,那么就加服務(wù)器。CPU是好東西,不能讓他干等,不做事情。
2.內(nèi)存:緩存從IIS進(jìn)程獨(dú)立出去,一般對WEB服務(wù)器來說內(nèi)存不夠的情況不是很多。內(nèi)存比磁盤快,要合理利用。
3.磁盤IO:用性能監(jiān)視器找到哪些文件IO特別大,找到了就分到獨(dú)立的一組文件服務(wù)器上去,或者直接做CDN。磁盤慢,大規(guī)模讀取數(shù)據(jù)的應(yīng)用靠緩存,大規(guī)模寫入數(shù)據(jù)的應(yīng)用可以靠隊(duì)列來降低突發(fā)的并發(fā)。
4.網(wǎng)絡(luò):我們知道,網(wǎng)絡(luò)的通訊是比較慢的,比磁盤還慢,如果是做分布式緩存,分布式計(jì)算的話,要考慮到物理服務(wù)器之間網(wǎng)絡(luò)通訊的時(shí)間,當(dāng)然,在流量大了以后,這可以提高系統(tǒng)的接納能力一個(gè)等級。靜態(tài)內(nèi)容可以借助CSD分擔(dān)一部分,在做服務(wù)器假設(shè)的時(shí)候還要考慮中國特色的電信網(wǎng)通情況以及防火墻。
四、對SQLSERVER數(shù)據(jù)庫服務(wù)器來說[UPDATE]:
其實(shí)還是水平分割和縱向分割,一個(gè)二維表,水平分割就是橫過來切一刀,縱向分割就是豎直切一刀:
1、縱向分割就是,我們不同的應(yīng)用可以分到不同的DB中,不同的實(shí)例中,或者說把某個(gè)擁有很多字段的表拆分成小表。
2、橫向分割就是,某些應(yīng)用可能不負(fù)載,比如用戶注冊,但是用戶表會非常大,可以把大表分開。可以采用表分區(qū),數(shù)據(jù)存儲在不同文件上,然后再部署到獨(dú)立物理服務(wù)器增加IO吞吐以改善讀寫性能,土一點(diǎn)的做法就是自己定期把老的數(shù)據(jù)存檔。表分區(qū)的另外一個(gè)優(yōu)勢可以增加數(shù)據(jù)查詢速度,因?yàn)槲覀兊捻撍饕梢杂卸鄬恿耍拖褚粋(gè)文件夾中的文件不要太多,多分幾層文件夾一樣。
3、還可以通過數(shù)據(jù)庫鏡像、復(fù)制訂閱、事物日志,把讀寫分開到不同的鏡像物理數(shù)據(jù)庫上,一般來說夠用,如果還不行可以用硬件來實(shí)現(xiàn)數(shù)據(jù)庫的負(fù)載均衡。當(dāng)然,對于BI,我們可能還會有數(shù)據(jù)倉庫。
架構(gòu)上考慮到了這些之后,流量大了,就可以在這個(gè)的基礎(chǔ)上再去調(diào)整或者做WEB服務(wù)器或者應(yīng)用服務(wù)器的負(fù)載均衡。很多時(shí)候我們都是在重復(fù)發(fā)現(xiàn)問題-》找到瓶頸-》解決這個(gè)過程。
五、典型的架構(gòu)如下:
動態(tài)WEB服務(wù)器配好點(diǎn)的CPU,靜態(tài)WEB服務(wù)器和文件服務(wù)器磁盤好點(diǎn)應(yīng)用服務(wù)器內(nèi)存大點(diǎn),緩存服務(wù)器也是,數(shù)據(jù)庫服務(wù)器當(dāng)然內(nèi)存和CPU都要好
擴(kuò)展閱讀:大型網(wǎng)站架構(gòu)方案分析與總結(jié)
大型網(wǎng)站架構(gòu)不得不考慮的10個(gè)問題
大型網(wǎng)站架構(gòu)只包括高互動性高交互性的數(shù)據(jù)型大型網(wǎng)站,基于大家眾所周知的原因,我們就不談新聞類和一些依靠HTML靜態(tài)化就可以實(shí)現(xiàn)的架構(gòu)了,我們以高負(fù)載高數(shù)據(jù)交換高數(shù)據(jù)流動性的網(wǎng)站為例,比如海內(nèi),開心網(wǎng)等類似的web2.0系列架構(gòu)。我們這里不討論是PHP還是JSP或者.NET環(huán)境,我們從架構(gòu)的方面去看問題,實(shí)現(xiàn)語言方面并不是問題,語言的優(yōu)勢在于實(shí)現(xiàn)而不是好壞,不論你選擇任何語言,架構(gòu)都是必須要面對的。
這里討論一下大型網(wǎng)站需要注意和考慮的問題。
1、海量數(shù)據(jù)的處理
眾所周知,對于一些相對小的站點(diǎn)來說,數(shù)據(jù)量并不是很大,select和update就可以解決我們面對的問題,本身負(fù)載量不是很大,最多再加幾個(gè)索引就可以搞定。對于大型網(wǎng)站,每天的數(shù)據(jù)量可能就上百萬,如果一個(gè)設(shè)計(jì)不好的多對多關(guān)系,在前期是沒有任何問題的,但是隨著用戶的增長,數(shù)據(jù)量會是幾何級的增長的。在這個(gè)時(shí)候我們對于一個(gè)表的select和update的時(shí)候(還不說多表聯(lián)合查詢)的成本的非常高的。
2、數(shù)據(jù)并發(fā)的處理
在一些時(shí)候,2.0的CTO都有個(gè)尚方寶劍,就是緩存。對于緩存,在高并發(fā)高處理的時(shí)候也是個(gè)大問題。在整個(gè)應(yīng)用程序下,緩存是全局共享的,然而在我們進(jìn)行修改的時(shí)候就,如果兩個(gè)或者多個(gè)請求同時(shí)對緩存有更新的要求的情況下,應(yīng)用程序會直接的死掉。這個(gè)時(shí)候,就需要一個(gè)好的數(shù)據(jù)并發(fā)處理策略以及緩存策略。
另外,就是數(shù)據(jù)庫的死鎖問題,也許平時(shí)我們感覺不到,死鎖在高并發(fā)的情況下的出現(xiàn)的概率是非常高的,磁盤緩存就是一個(gè)大問題。
3、文件存貯的問題
對于一些支持文件上傳的2.0的站點(diǎn),在慶幸硬盤容量越來越大的時(shí)候我們更多的應(yīng)該考慮的是文件應(yīng)該如何被存儲并且被有效的索引。常見的方案是對文件按照日期和類型進(jìn)行存貯。但是當(dāng)文件量是海量的數(shù)據(jù)的情況下,如果一塊硬盤存貯了500個(gè)G的瑣碎文件,那么維護(hù)的時(shí)候和使用的時(shí)候磁盤的Io就是一個(gè)巨大的問題,哪怕你的帶寬足夠,但是你的磁盤也未必響應(yīng)過來。如果這個(gè)時(shí)候還涉及上傳,磁盤很容易就over了。
也許用raid和專用存貯服務(wù)器能解決眼下的問題,但是還有個(gè)問題就是各地的訪問問題,也許我們的服務(wù)器在北京,可能在云南或者新疆的訪問速度如何解決?如果做分布式,那么我們的文件索引以及架構(gòu)該如何規(guī)劃。
所以我們不得不承認(rèn),文件存貯是個(gè)很不容易的問題4、數(shù)據(jù)關(guān)系的處理
我們可以很容易的規(guī)劃出一個(gè)符合第三范式的數(shù)據(jù)庫,里面布滿了多對多關(guān)系,還能用GUID來替換INDENTIFYCOLUMN但是,多對多關(guān)系充斥的2.0時(shí)代,第三范式是第一個(gè)應(yīng)該被拋棄的。必須有效的把多表聯(lián)合查詢降到最低。
5、數(shù)據(jù)索引的問題
眾所周知,索引是提高數(shù)據(jù)庫效率查詢的最方面最廉價(jià)最容易實(shí)現(xiàn)的方案。但是,在高UPDATE的情況下,update和delete付出的成本會高的無法想想,筆者遇到過一個(gè)情況,在更新一個(gè)聚焦索引的時(shí)候需要10分鐘來完成,那么對于站點(diǎn)來說,這些基本上是不可忍受的。
索引和更新是一對天生的冤家,問題A,D,E這些是我們在做架構(gòu)的時(shí)候不得不考慮的問題,并且也可能是花費(fèi)時(shí)間最多的問題。
6、分布式處理
對于2.0網(wǎng)站由于其高互動性,CDN實(shí)現(xiàn)的效果基本上為0,內(nèi)容是實(shí)時(shí)更新的,我們常規(guī)的處理。為了保證各地的訪問速度,我們就需要面對一個(gè)絕大的問題,就是如何有效的實(shí)現(xiàn)數(shù)據(jù)同步和更新,實(shí)現(xiàn)各地服務(wù)器的實(shí)時(shí)通訊有是一個(gè)不得不需要考慮的問題。
7、Ajax的利弊分析
成也AJAX,敗也AJAX,AJAX成為了主流趨勢,突然發(fā)現(xiàn)基于XMLHTTP的post和get是如此的容易?蛻舳薵et或者post到服務(wù)器數(shù)據(jù),服務(wù)器接到數(shù)據(jù)請求之后返回來,這是一個(gè)很正常的AJAX請求。但是在AJAX處理的時(shí)候,如果我們使用一個(gè)抓包工具的話,對數(shù)據(jù)返回和處理是一目了然。對于一些計(jì)算量大的AJAX請求的話,我們可以構(gòu)造一個(gè)發(fā)包機(jī),很容易就可以把一個(gè)webserver干掉。
8、數(shù)據(jù)安全性的分析
對于HTTP協(xié)議來說,數(shù)據(jù)包都是明文傳輸?shù)模苍S我們可以說我們可以用加密啊,但是對于G問題來說的話,加密的過程就可能是明文了(比如我們知道的QQ,可以很容易的判斷他的加密,并有效的寫一個(gè)跟他一樣的加密和解密方法出來的)。當(dāng)你站點(diǎn)流量不是很大的時(shí)候沒有人會在乎你,但是當(dāng)你流量上來之后,那么所謂的外掛,所謂的群發(fā)就會接踵而來(從qq一開始的群發(fā)可見端倪)。也許我們可以很的意的說,我們可以采用更高級別的判斷甚至HTTPS來實(shí)現(xiàn),注意,當(dāng)你做這些處理的時(shí)候付出的將是海量的database,io以及CPU的成本。對于一些群發(fā),基本上是不可能的。筆者已經(jīng)可以實(shí)現(xiàn)對于百度空間和qq空間的群發(fā)了。大家愿意試試,實(shí)際上并不是很難。
9、數(shù)據(jù)同步和集群的處理的問題
當(dāng)我們的一臺databaseserver不堪重負(fù)的時(shí)候,這個(gè)時(shí)候我們就需要做基于數(shù)據(jù)庫的負(fù)載和集群了。而這個(gè)時(shí)候可能是最讓人困擾的的問題了,數(shù)據(jù)基于網(wǎng)絡(luò)傳輸根據(jù)數(shù)據(jù)庫的設(shè)計(jì)的不同,數(shù)據(jù)延遲是很可怕的問題,也是不可避免的問題,這樣的話,我們就需要通過另外的手段來保證在這延遲的幾秒或者更長的幾分鐘時(shí)間內(nèi),實(shí)現(xiàn)有效的交互。比如數(shù)據(jù)散列,分割,內(nèi)容處理等等問題。
10、數(shù)據(jù)共享的渠道以及OPENAPI趨勢
Openapi已經(jīng)成為一個(gè)不可避免的趨勢,從google,facebook,myspace到21kaiyun.com,都在考慮這個(gè)問題,它可以更有效的留住用戶并激發(fā)用戶的更多的興趣以及讓更多的人幫助你做最有效的開發(fā)。這個(gè)時(shí)候一個(gè)有效的數(shù)據(jù)共享平臺,數(shù)據(jù)開放平臺就成為必不可少的途徑了,而在開放的接口的情況保證數(shù)據(jù)的安全性和性能,又是一個(gè)我們必須要認(rèn)真思考的問題了。
大型網(wǎng)站數(shù)據(jù)庫優(yōu)化
千萬人同時(shí)訪問的網(wǎng)站,一般是有很多個(gè)數(shù)據(jù)庫同時(shí)工作,說明白一點(diǎn)就是數(shù)據(jù)庫集群和并發(fā)控制,這樣的網(wǎng)站實(shí)時(shí)性也是相對的。這些網(wǎng)站都有一些共同的特點(diǎn):數(shù)據(jù)量大,在線人數(shù)多,并發(fā)請求多,pageview高,響應(yīng)速度快。總結(jié)了一下各個(gè)大網(wǎng)站的架構(gòu),主要提高效率及穩(wěn)定性的幾個(gè)地方包括:
1、程序
程序開發(fā)是一方面,系統(tǒng)架構(gòu)設(shè)計(jì)(硬件+網(wǎng)絡(luò)+軟件)是另一方面。
軟件架構(gòu)方面,做網(wǎng)站首先需要很多web服務(wù)器存儲靜態(tài)資源,比如圖片、視頻、靜態(tài)頁等,千萬不要把靜態(tài)資源和應(yīng)用服務(wù)器放在一起。
一個(gè)好的程序員寫出來的程序會非常簡潔、性能很好,一個(gè)初級程序員可能會犯很多低級錯誤,這也是影響網(wǎng)站性能的原因之一。
網(wǎng)站要做到效率高,不光是程序員的事情,數(shù)據(jù)庫優(yōu)化、程序優(yōu)化這是必須的,在性能優(yōu)化上要數(shù)據(jù)庫和程序齊頭并進(jìn)!緩存也是兩方面同時(shí)入手。第一,數(shù)據(jù)庫緩存和數(shù)據(jù)庫優(yōu)化,這個(gè)由dba完成(而且這個(gè)有非常大的潛力可挖,只是由于我們都是程序員而忽略了他而已)。第二,程序上的優(yōu)化,這個(gè)非常的有講究,比如說重要一點(diǎn)就是要規(guī)范SQL語句,少用in多用or,多用preparestatement,另外避免程序冗余如查找數(shù)據(jù)少用雙重循環(huán)等。另外選用優(yōu)秀的開源框架加以支持,我個(gè)人認(rèn)為中后臺的支持是最最重要的,可以選取spring+ibatis。因?yàn)閕batis直接操作SQL并有緩存機(jī)制。spring的好處就不用我多說了,IOC的機(jī)制可以避免new對象,這樣也節(jié)省開銷。據(jù)我分析,絕大部分的開銷就是在NEW的時(shí)候和連接數(shù)據(jù)庫時(shí)候產(chǎn)生的,請盡量避免。另外可以用一些內(nèi)存測試工具來做一個(gè)demo說明hibernate和ibatis誰更快!前臺你想用什么就用什么,struts,webwork都成,如果覺得自己挺牛X可以試試用tapestry。
用數(shù)據(jù)庫也未必不能解決訪問量巨大所帶來的問題,作成靜態(tài)文件硬盤的尋址時(shí)間也未必少于數(shù)據(jù)庫的搜索時(shí)間,當(dāng)然對資料的索引要下一翻工夫。我自己覺得門戶往往也就是當(dāng)天、熱門的資料點(diǎn)擊率較高,將其做緩存最多也不過1~2G的數(shù)據(jù)量吧,舉個(gè)例子:
◎拿網(wǎng)易新聞來說格式化一下,方便理解:http://域名/年/月日/新聞所屬分類/新聞ID.html
可以把當(dāng)天發(fā)布的、熱門的、流攬量大的作個(gè)緩寸,用hashtable(key:年-月-日-分類-ID,value:新聞對象),靜態(tài)將其放到內(nèi)存(速度絕對快過硬盤尋址靜態(tài)頁面)。
通常是采用oracle存儲過程+2個(gè)weblogic,更新機(jī)制也幾乎一樣每簽發(fā)一條新聞,就會生成靜態(tài)頁面,然后發(fā)往前端的web服務(wù)器,前端的web都是做負(fù)載均衡的。另外還有定時(shí)的程序,每5-15分鐘自動生成一次。在發(fā)布新聞的同時(shí)將數(shù)據(jù)緩存。當(dāng)然緩存也不會越來越大,在個(gè)特定的時(shí)間段(如凌晨)剔除過期的數(shù)據(jù)。做一個(gè)大的網(wǎng)站遠(yuǎn)沒有想象中那么簡單,服務(wù)器基本就要百十個(gè)的。
這樣可以大大增加一臺計(jì)算機(jī)的處理速度,如果一臺機(jī)器處理不了,可以用httpserver集群來解決問題了。
2、網(wǎng)絡(luò)
中國的網(wǎng)絡(luò)分南北電信和網(wǎng)通,訪問的ip就要區(qū)分南北進(jìn)入不同的網(wǎng)絡(luò)。3、集群
通常會使用CDN與GSBL與DNS負(fù)載均衡技術(shù),每個(gè)地區(qū)一組前臺服務(wù)器群,例如:網(wǎng)易,百度使用了DNS負(fù)載均衡技術(shù),每個(gè)頻道一組前臺服務(wù)器,一搜使用了DNS負(fù)載技術(shù),所有頻道共用一組前臺服務(wù)器集群。
網(wǎng)站使用基于Linux集群的負(fù)載均衡,失敗恢復(fù),包括應(yīng)用服務(wù)器和數(shù)據(jù)庫服務(wù)器,基于linux-ha的服務(wù)狀態(tài)檢測及高可用化。
應(yīng)用服務(wù)器集群可以采用apache+tomcat集群和weblogic集群等;web服務(wù)器集群可以用反向代理,也可以用NAT的方式,或者多域名解析都可以;Squid也可以,方法很多,可以根據(jù)情況選擇。4、數(shù)據(jù)庫
因?yàn)槭乔f人同時(shí)訪問的網(wǎng)站,所以一般是有很多個(gè)數(shù)據(jù)庫同時(shí)工作的,說明白一點(diǎn)就是數(shù)據(jù)庫集群和并發(fā)控制,數(shù)據(jù)分布到地理位置不同的數(shù)據(jù)中心,以免發(fā)生斷電事故。另外還有一點(diǎn)的是,那些網(wǎng)站的靜態(tài)化網(wǎng)頁并不是真的,而是通過動態(tài)網(wǎng)頁與靜態(tài)網(wǎng)頁網(wǎng)址交換做出現(xiàn)的假象,這可以用urlrewrite這樣的開源網(wǎng)址映射器實(shí)現(xiàn)。這樣的網(wǎng)站實(shí)時(shí)性也是相對的,因?yàn)樵跀?shù)據(jù)庫復(fù)制數(shù)據(jù)的時(shí)候有一個(gè)過程,一般在技術(shù)上可以用到hibernate和ecache,但是如果要使網(wǎng)站工作地更好,可以使用EJB和websphere,weblogic這樣大型的服務(wù)器來支持,并且要用oracle這樣的大型數(shù)據(jù)庫。
大型門戶網(wǎng)站不建議使用Mysql數(shù)據(jù)庫,除非你對Mysql數(shù)據(jù)的優(yōu)化非常熟悉。Mysql數(shù)據(jù)庫服務(wù)器的master-slave模式,利用數(shù)據(jù)庫服務(wù)器在主從服務(wù)器間進(jìn)行同步,應(yīng)用只把數(shù)據(jù)寫到主服務(wù)器,而讀數(shù)據(jù)時(shí)則根據(jù)負(fù)載選擇一臺從服務(wù)器或者主服務(wù)器來讀取,將數(shù)據(jù)按不同策略劃分到不同的服務(wù)器(組)上,分散數(shù)據(jù)庫壓力。
大型網(wǎng)站要用oracle,數(shù)據(jù)方面操作盡量多用存儲過程,絕對提升性能;同時(shí)要讓DBA對數(shù)據(jù)庫進(jìn)行優(yōu)化,優(yōu)化后的數(shù)據(jù)庫與沒優(yōu)化的有天壤之別;同時(shí)還可以擴(kuò)展分布式數(shù)據(jù)庫,以后這方面的研究會越來越多;
5、頁面
從開始就考慮使用虛擬存儲/簇文件系統(tǒng)。它能讓你大量并行IO訪問,而且不需要任何重組就能夠增加所需要的磁盤。頁面數(shù)據(jù)調(diào)用更要認(rèn)真設(shè)計(jì),一些數(shù)據(jù)查詢可以不通過數(shù)據(jù)庫的方式,實(shí)時(shí)性要求不高的可以使用lucene來實(shí)現(xiàn),即使有實(shí)時(shí)性的要求也可以用lucene,lucene+compass還是非常優(yōu)秀的。
新聞類的網(wǎng)站可以用靜態(tài)頁存儲,采用定時(shí)更新機(jī)制減輕服務(wù)器負(fù)擔(dān);首頁每個(gè)小模塊可以使用oscache緩存,這樣不用每次都拉數(shù)據(jù)。
前端的基于靜態(tài)頁面緩存的web加速器,主要應(yīng)用有squid等。squid將大部分靜態(tài)資源(圖片,js,css等)緩存起來,直接返回給訪問者,減少應(yīng)用服務(wù)器的負(fù)載網(wǎng)站的靜態(tài)化網(wǎng)頁并不是真的,而是通過動態(tài)網(wǎng)頁與靜態(tài)網(wǎng)頁網(wǎng)址交換做出現(xiàn)的假象,這可以用urlrewrite這樣的開源網(wǎng)址映射器實(shí)現(xiàn),后綴名為htm或者h(yuǎn)tml并不能說明程序生成了靜態(tài)頁面,可能是通過url重寫來實(shí)現(xiàn)的,為的只不過是在搜索引擎中提升自己網(wǎng)站的覆蓋面積罷了。
生成靜態(tài)頁面的服務(wù)器和www服務(wù)器是兩組不同的服務(wù)器,頁面生成后才會到www服務(wù)器,一部分?jǐn)?shù)據(jù)庫并不是關(guān)系數(shù)據(jù)庫,這樣更適合信息衍生,www、mail服務(wù)器、路由器多,主要用負(fù)載平衡解決訪問瓶頸!蜢o態(tài)頁面的缺點(diǎn):1)增加了程序的復(fù)雜度2)不利于管理資料3)速度不是最快4)傷硬盤
6、緩存
從一開始就應(yīng)該使用緩存,高速緩存是一個(gè)更好的地方存儲臨時(shí)數(shù)據(jù),比如Web站點(diǎn)上跟蹤一個(gè)特定用戶的會話產(chǎn)生的臨時(shí)文件,就不再需要記錄到數(shù)據(jù)庫里。
不能用lucene實(shí)現(xiàn)的可以用緩存,分布式緩存可以用memcached,如果有錢的話用10來臺機(jī)器做緩存,>10G的存儲量相信存什么都夠了;如果沒錢的話可以在頁面緩存和數(shù)據(jù)緩存上下功夫,多用OSCACHE和EHCACHE,SWARMCACHE也可以,不過據(jù)說同步性不是很好;
可以使用Memcache進(jìn)行緩存,用大內(nèi)存把這些不變的數(shù)據(jù)全都緩存起來,而當(dāng)修改時(shí)就通知cache過期,memcache是LJ開發(fā)的一款分布式緩存產(chǎn)品,很多大型網(wǎng)站在應(yīng)用,我們可以把CacheServer與AppServer裝在一起。因?yàn)镃acheServer對CPU消耗不大,而有了CacheServer的支援,AppServer對內(nèi)存要求也不是太高,所以可以和平共處,更有效的利用資源。
以上一些不太成熟的想法,可以從某一個(gè)層次開始,逐步細(xì)化,把產(chǎn)品的性能指標(biāo)提高上去。
淺析大型網(wǎng)站的架構(gòu)
一個(gè)小型的網(wǎng)站,比如個(gè)人網(wǎng)站,可以使用最簡單的html靜態(tài)頁面就實(shí)現(xiàn)了,配合一些圖片達(dá)到美化效果,所有的頁面均存放在一個(gè)目錄下,這樣的網(wǎng)站對系統(tǒng)架構(gòu)、性能的要求都很簡單,隨著互聯(lián)網(wǎng)業(yè)務(wù)的不斷豐富,網(wǎng)站相關(guān)的技術(shù)經(jīng)過這些年的發(fā)展,已經(jīng)細(xì)分到很細(xì)的方方面面,尤其對于大型網(wǎng)站來說,所采用的技術(shù)更是涉及面非常廣,從硬件到軟件、編程語言、數(shù)據(jù)庫、WebServer、防火墻等各個(gè)領(lǐng)域都有了很高的要求,已經(jīng)不是原來簡單的html靜態(tài)網(wǎng)站所能比擬的。
大型網(wǎng)站,比如門戶網(wǎng)站。在面對大量用戶訪問、高并發(fā)請求方面,基本的解決方案集中在這樣幾個(gè)環(huán)節(jié):使用高性能的服務(wù)器、高性能的數(shù)據(jù)庫、高效率的編程語言、還有高性能的Web容器。但是除了這幾個(gè)方面,還沒法根本解決大型網(wǎng)站面臨的高負(fù)載和高并發(fā)問題。上面提供的幾個(gè)解決思路在一定程度上也意味著更大的投入,并且這樣的解決思路具備瓶頸,沒有很好的擴(kuò)展性,下面我從低成本、高性能和高擴(kuò)張性的角度來說說我的一些經(jīng)驗(yàn)。
1、HTML靜態(tài)化
其實(shí)大家都知道,效率最高、消耗最小的就是純靜態(tài)化的html頁面,所以我們盡可能使我們的網(wǎng)站上的頁面采用靜態(tài)頁面來實(shí)現(xiàn),這個(gè)最簡單的方法其實(shí)也是最有效的方法。但是對于大量內(nèi)容并且頻繁更新的網(wǎng)站,我們無法全部手動去挨個(gè)實(shí)現(xiàn),于是出現(xiàn)了我們常見的信息發(fā)布系統(tǒng)CMS,像我們常訪問的各個(gè)門戶站點(diǎn)的新聞頻道,甚至他們的其他頻道,都是通過信息發(fā)布系統(tǒng)來管理和實(shí)現(xiàn)的,信息發(fā)布系統(tǒng)可以實(shí)現(xiàn)最簡單的信息錄入自動生成靜態(tài)頁面,還能具備頻道管理、權(quán)限管理、自動抓取等功能,對于一個(gè)大型網(wǎng)站來說,擁有一套高效、可管理的CMS是必不可少的。除了門戶和信息發(fā)布類型的網(wǎng)站,對于交互性要求很高的社區(qū)類型網(wǎng)站來說,盡可能的靜態(tài)化也是提高性能的必要手段,將社區(qū)內(nèi)的帖子、文章進(jìn)行實(shí)時(shí)的靜態(tài)化,有更新的時(shí)候再重新靜態(tài)化也是大量使用的策略,像Mop的大雜燴就是使用了這樣的策略,網(wǎng)易社區(qū)等也是如此。
同時(shí),html靜態(tài)化也是某些緩存策略使用的手段,對于系統(tǒng)中頻繁使用數(shù)據(jù)庫查詢但是內(nèi)容更新很小的應(yīng)用,可以考慮使用html靜態(tài)化來實(shí)現(xiàn),比如論壇中論壇的公用設(shè)置信息,這些信息目前的主流論壇都可以進(jìn)行后臺管理并且存儲再數(shù)據(jù)庫中,這些信息其實(shí)大量被前臺程序調(diào)用,但是更新頻率很小,可以考慮將這部分內(nèi)容進(jìn)行后臺更新的時(shí)候進(jìn)行靜態(tài)化,這樣避免了大量的數(shù)據(jù)庫訪問請求。
2、圖片服務(wù)器分離
大家知道,對于Web服務(wù)器來說,不管是Apache、IIS還是其他容器,圖片是最消耗資源的,于是我們有必要將圖片與頁面進(jìn)行分離,這是基本上大型網(wǎng)站都會采用的策略,他們都有獨(dú)立的圖片服務(wù)器,甚至很多臺圖片服務(wù)器。這樣的架構(gòu)可以降低提供頁面訪問請求的服務(wù)器系統(tǒng)壓力,并且可以保證系統(tǒng)不會因?yàn)閳D片問題而崩潰,在應(yīng)用服務(wù)器和圖片服務(wù)器上,可以進(jìn)行不同的配置優(yōu)化,比如apache在配置ContentType的時(shí)候可以盡量少支持,盡可能少的LoadModule,保證更高的系統(tǒng)消耗和執(zhí)行效率。
3、數(shù)據(jù)庫集群和庫表散列
大型網(wǎng)站都有復(fù)雜的應(yīng)用,這些應(yīng)用必須使用數(shù)據(jù)庫,那么在面對大量訪問的時(shí)候,數(shù)據(jù)庫的瓶頸很快就能顯現(xiàn)出來,這時(shí)一臺數(shù)據(jù)庫將很快無法滿足應(yīng)用,于是我們需要使用數(shù)據(jù)庫集群或者庫表散列。
在數(shù)據(jù)庫集群方面,很多數(shù)據(jù)庫都有自己的解決方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是類似的方案,您使用了什么樣的DB,就參考相應(yīng)的解決方案來實(shí)施即可。
上面提到的數(shù)據(jù)庫集群由于在架構(gòu)、成本、擴(kuò)張性方面都會受到所采用DB類型的限制,于是我們需要從應(yīng)用程序的角度來考慮改善系統(tǒng)架構(gòu),庫表散列是常用并且最有效的解決方案。我們在應(yīng)用程序中安裝業(yè)務(wù)和應(yīng)用或者功能模塊將數(shù)據(jù)庫進(jìn)行分離,不同的模塊對應(yīng)不同的數(shù)據(jù)庫或者表,再按照一定的策略對某個(gè)頁面或者功能進(jìn)行更小的數(shù)據(jù)庫散列,比如用戶表,按照用戶ID進(jìn)行表散列,這樣就能夠低成本的提升系統(tǒng)的性能并且有很好的擴(kuò)展性。sohu的論壇就是采用了這樣的架構(gòu),將論壇的用戶、設(shè)置、帖子等信息進(jìn)行數(shù)據(jù)庫分離,然后對帖子、用戶按照板塊和ID進(jìn)行散列數(shù)據(jù)庫和表,最終可以在配置文件中進(jìn)行簡單的配置便能讓系統(tǒng)隨時(shí)增加一臺低成本的數(shù)據(jù)庫進(jìn)來補(bǔ)充系統(tǒng)性能。
4、緩存
緩存一詞搞技術(shù)的都接觸過,很多地方用到緩存。網(wǎng)站架構(gòu)和網(wǎng)站開發(fā)中的緩存也是非常重要。這里先講述最基本的兩種緩存。高級和分布式的緩存在后面講述。
架構(gòu)方面的緩存,對Apache比較熟悉的人都能知道Apache提供了自己的緩存模塊,也可以使用外加的Squid模塊進(jìn)行緩存,這兩種方式均可以有效的提高Apache的訪問響應(yīng)能力。網(wǎng)站程序開發(fā)方面的緩存,Linux上提供的MemoryCache是常用的緩存接口,可以在web開發(fā)中使用,比如用Java開發(fā)的時(shí)候就可以調(diào)用MemoryCache對一些數(shù)據(jù)進(jìn)行緩存和通訊共享,一些大型社區(qū)使用了這樣的架構(gòu)。另外,在使用web語言開發(fā)的時(shí)候,各種語言基本都有自己的緩存模塊和方法,PHP有Pear的Cache模塊,Java就更多了,.net不是很熟悉,相信也肯定有。
5、鏡像
鏡像是大型網(wǎng)站常采用的提高性能和數(shù)據(jù)安全性的方式,鏡像的技術(shù)可以解決不同網(wǎng)絡(luò)接入商和地域帶來的用戶訪問速度差異,比如ChinaNet和EduNet之間的差異就促使了很多網(wǎng)站在教育網(wǎng)內(nèi)搭建鏡像站點(diǎn),數(shù)據(jù)進(jìn)行定時(shí)更新或者實(shí)時(shí)更新。在鏡像的細(xì)節(jié)技術(shù)方面,這里不闡述太深,有很多專業(yè)的現(xiàn)成的解決架構(gòu)和產(chǎn)品可選。也有廉價(jià)的通過軟件實(shí)現(xiàn)的思路,比如Linux上的rsync等工具。
6、負(fù)載均衡
負(fù)載均衡將是大型網(wǎng)站解決高負(fù)荷訪問和大量并發(fā)請求采用的終極解決辦法。負(fù)載均衡技術(shù)發(fā)展了多年,有很多專業(yè)的服務(wù)提供商和產(chǎn)品可以選擇,我個(gè)人接觸過一些解決方法,其中有兩個(gè)架構(gòu)可以給大家做參考。硬件四層交換
第四層交換使用第三層和第四層信息包的報(bào)頭信息,根據(jù)應(yīng)用區(qū)間識別業(yè)務(wù)流,將整個(gè)區(qū)間段的業(yè)務(wù)流分配到合適的應(yīng)用服務(wù)器進(jìn)行處理。第四層交換功能就象是虛IP,指向物理服務(wù)器。它傳輸?shù)臉I(yè)務(wù)服從的協(xié)議多種多樣,有HTTP、FTP、NFS、Telnet或其他協(xié)議。這些業(yè)務(wù)在物理服務(wù)器基礎(chǔ)上,需要復(fù)雜的載量平衡算法。在IP世界,業(yè)務(wù)類型由終端TCP或UDP端口地址來決定,在第四層交換中的應(yīng)用區(qū)間則由源端和終端IP地址、TCP和UDP端口共同決定。
在硬件四層交換產(chǎn)品領(lǐng)域,有一些知名的產(chǎn)品可以選擇,比如Alteon、F5等,這些產(chǎn)品很昂貴,但是物有所值,能夠提供非常優(yōu)秀的性能和很靈活的管理能力。Yahoo中國當(dāng)初接近201*臺服務(wù)器使用了三四臺Alteon就搞定了。軟件四層交換
大家知道了硬件四層交換機(jī)的原理后,基于OSI模型來實(shí)現(xiàn)的軟件四層交換也就應(yīng)運(yùn)而生,這樣的解決方案實(shí)現(xiàn)的原理一致,不過性能稍差。但是滿足一定量的壓力還是游刃有余的,有人說軟件實(shí)現(xiàn)方式其實(shí)更靈活,處理能力完全看你配置的熟悉能力。
軟件四層交換我們可以使用Linux上常用的LVS來解決,LVS就是LinuxVirtualServer,他提供了基于心跳線heartbeat的實(shí)時(shí)災(zāi)難應(yīng)對解決方案,提高系統(tǒng)的魯棒性,同時(shí)可供了靈活的虛擬VIP配置和管理功能,可以同時(shí)滿足多種應(yīng)用需求,這對于分布式的系統(tǒng)來說必不可少。
一個(gè)典型的使用負(fù)載均衡的策略就是,在軟件或者硬件四層交換的基礎(chǔ)上搭建squid集群,這種思路在很多大型網(wǎng)站包括搜索引擎上被采用,這樣的架構(gòu)低成本、高性能還有很強(qiáng)的擴(kuò)張性,隨時(shí)往架構(gòu)里面增減節(jié)點(diǎn)都非常容易。這樣的架構(gòu)我準(zhǔn)備空了專門詳細(xì)整理一下和大家探討。
對于大型網(wǎng)站來說,前面提到的每個(gè)方法可能都會被同時(shí)使用到,我這里介紹得比較淺顯,具體實(shí)現(xiàn)過程中很多細(xì)節(jié)還需要大家慢慢熟悉和體會,有時(shí)一個(gè)很小的squid參數(shù)或者apache參數(shù)設(shè)置,對于系統(tǒng)性能的影響就會很大,希望大家一起討論,達(dá)到拋磚引玉之效。
淺談大型網(wǎng)站動態(tài)應(yīng)用系統(tǒng)架構(gòu)
動態(tài)應(yīng)用,是相對于網(wǎng)站靜態(tài)內(nèi)容而言,是指以c/c++、php、Java、perl、.net等服務(wù)器端語言開發(fā)的網(wǎng)絡(luò)應(yīng)用軟件,比如論壇、網(wǎng)絡(luò)相冊、交友、BLOG等常見應(yīng)用。動態(tài)應(yīng)用系統(tǒng)通常與數(shù)據(jù)庫系統(tǒng)、緩存系統(tǒng)、分布式存儲系統(tǒng)等密不可分。大型動態(tài)應(yīng)用系統(tǒng)平臺主要是針對于大流量、高并發(fā)網(wǎng)站建立的底層系統(tǒng)架構(gòu)。大型網(wǎng)站的運(yùn)行需要一個(gè)可靠、安全、可擴(kuò)展、易維護(hù)的應(yīng)用系統(tǒng)平臺做為支撐,以保證網(wǎng)站應(yīng)用的平穩(wěn)運(yùn)行。大型動態(tài)應(yīng)用系統(tǒng)又可分為幾個(gè)子系統(tǒng):1)Web前端系統(tǒng)2)負(fù)載均衡系統(tǒng)3)數(shù)據(jù)庫集群系統(tǒng)4)緩存系統(tǒng)5)分布式存儲系統(tǒng)6)分布式服務(wù)器管理系統(tǒng)7)代碼分發(fā)系統(tǒng)Web前端系統(tǒng)結(jié)構(gòu)圖:
為了達(dá)到不同應(yīng)用的服務(wù)器共享、避免單點(diǎn)故障、集中管理、統(tǒng)一配置等目的,不以應(yīng)用劃分服務(wù)器,而是將所有服務(wù)器做統(tǒng)一使用,每臺服務(wù)器都可以對多個(gè)應(yīng)用提供服務(wù),當(dāng)某些應(yīng)用訪問量升高時(shí),通過增加服務(wù)器節(jié)點(diǎn)達(dá)到整個(gè)服務(wù)器集群的性能提高,同時(shí)使他應(yīng)用也會受益。該Web前端系統(tǒng)基于
Apache/Lighttpd/Eginx等的虛擬主機(jī)平臺,提供PHP程序運(yùn)行環(huán)境。服務(wù)器對開發(fā)人員是透明的,不需要開發(fā)人員介入服務(wù)器管理負(fù)載均衡系統(tǒng)
負(fù)載均衡系統(tǒng)分為硬件和軟件兩種。硬件負(fù)載均衡效率高,但是價(jià)格貴,比如F5等。軟件負(fù)載均衡系統(tǒng)價(jià)格較低或者免費(fèi),效率較硬件負(fù)載均衡系統(tǒng)低,不過對于流量一般或稍大些網(wǎng)站來講也足夠使用,比如lvs,nginx。大多數(shù)網(wǎng)站都是硬件、軟件負(fù)載均衡系統(tǒng)并用。數(shù)據(jù)庫集群系統(tǒng)結(jié)構(gòu)圖:
由于Web前端采用了負(fù)載均衡集群結(jié)構(gòu)提高了服務(wù)的有效性和擴(kuò)展性,因此數(shù)據(jù)庫必須也是高可靠的,才能保證整個(gè)服務(wù)體系的高可靠性,如何構(gòu)建一個(gè)高可靠的、可以提供大規(guī)模并發(fā)處理的數(shù)據(jù)庫體系?我們可以采用如上圖所示的方案:
1)使用MySQL數(shù)據(jù)庫,考慮到Web應(yīng)用的數(shù)據(jù)庫讀多寫少的特點(diǎn),我們主要對讀數(shù)據(jù)庫做了優(yōu)化,提供專用的讀數(shù)據(jù)庫和寫數(shù)據(jù)庫,在應(yīng)用程序中實(shí)現(xiàn)讀操作和寫操作分別訪問不同的數(shù)據(jù)庫。2)使用MySQLReplication機(jī)制實(shí)現(xiàn)快速將主庫(寫庫)的數(shù)據(jù)庫復(fù)制到從庫(讀庫)。一個(gè)主庫對應(yīng)多個(gè)從庫,主庫數(shù)據(jù)實(shí)時(shí)同步到從庫。3)寫數(shù)據(jù)庫有多臺,每臺都可以提供多個(gè)應(yīng)用共同使用,這樣可以解決寫庫的性能瓶頸問題和單點(diǎn)故障問題。
4)讀數(shù)據(jù)庫有多臺,通過負(fù)載均衡設(shè)備實(shí)現(xiàn)負(fù)載均衡,從而達(dá)到讀數(shù)據(jù)庫的高性能、高可靠和高可擴(kuò)展性。5)數(shù)據(jù)庫服務(wù)器和應(yīng)用服務(wù)器分離。6)從數(shù)據(jù)庫使用BigIP做負(fù)載均衡。緩存系統(tǒng)
緩存分為文件緩存、內(nèi)存緩存、數(shù)據(jù)庫緩存。在大型Web應(yīng)用中使用最多且效率最高的是內(nèi)存緩存。最常用的內(nèi)存緩存工具是Memcached。使用正確的緩存系統(tǒng)可以達(dá)到實(shí)現(xiàn)以下目標(biāo):
1、使用緩存系統(tǒng)可以提高訪問效率,提高服務(wù)器吞吐能力,改善用戶體驗(yàn)。2、減輕對數(shù)據(jù)庫及存儲集服務(wù)器的訪問壓力。
3、Memcached服務(wù)器有多臺,避免單點(diǎn)故障,提供高可靠性和可擴(kuò)展性,提高性能。
分布式存儲系統(tǒng)結(jié)構(gòu)圖:
Web系統(tǒng)平臺中的存儲需求有下面兩個(gè)特點(diǎn):
1)存儲量很大,經(jīng)常會達(dá)到單臺服務(wù)器無法提供的規(guī)模,比如相冊、視頻等應(yīng)用。因此需要專業(yè)的大規(guī)模存儲系統(tǒng)。
2)負(fù)載均衡cluster中的每個(gè)節(jié)點(diǎn)都有可能訪問任何一個(gè)數(shù)據(jù)對象,每個(gè)節(jié)點(diǎn)對數(shù)據(jù)的處理也能被其他節(jié)點(diǎn)共享,因此這些節(jié)點(diǎn)要操作的數(shù)據(jù)從邏輯上看只能是一個(gè)整體,不是各自獨(dú)立的數(shù)據(jù)資源。
因此高性能的分布式存儲系統(tǒng)對于大型網(wǎng)站應(yīng)用來說是非常重要的一環(huán)。(這個(gè)地方需要加入對某個(gè)分布式存儲系統(tǒng)的簡單介紹。)分布式服務(wù)器管理系統(tǒng)結(jié)構(gòu)圖:
隨著網(wǎng)站訪問流量的不斷增加,大多的網(wǎng)絡(luò)服務(wù)都是以負(fù)載均衡集群的方式對外提供服務(wù),隨之集群規(guī)模的擴(kuò)大,原來基于單機(jī)的服務(wù)器管理模式已經(jīng)不能夠滿足我們的需求,新的需求必須能夠集中式的、分組的、批量的、自動化的對服務(wù)器進(jìn)行管理,能夠批量化的執(zhí)行計(jì)劃任務(wù)。
在分布式服務(wù)器管理系統(tǒng)軟件中有一些比較優(yōu)秀的軟件,其中比較理想的一個(gè)是Cfengine。它可以對服務(wù)器進(jìn)行分組,不同的分組可以分別定制系統(tǒng)配置文件、計(jì)劃任務(wù)等配置。它是基于C/S結(jié)構(gòu)的,所有的服務(wù)器配置和管理腳本程序都保存在CfengineServer上,而被管理的服務(wù)器運(yùn)行著CfengineClient程序,CfengineClient通過SSL加密的連接定期的向服務(wù)器端發(fā)送請求以獲取最新的配置文件和管理命令、腳本程序、補(bǔ)丁安裝等任務(wù)。
有了Cfengine這種集中式的服務(wù)器管理工具,我們就可以高效的實(shí)現(xiàn)大規(guī)模的服務(wù)器集群管理,被管理服務(wù)器和CfengineServer可以分布在任何位置,只要網(wǎng)絡(luò)可以連通就能實(shí)現(xiàn)快速自動化的管理。代碼發(fā)布系統(tǒng)結(jié)構(gòu)圖:
隨著網(wǎng)站訪問流量的不斷增加,大多的網(wǎng)絡(luò)服務(wù)都是以負(fù)載均衡集群的方式對外提供服務(wù),隨之集群規(guī)模的擴(kuò)大,為了滿足集群環(huán)境下程序代碼的批量分發(fā)和更新,我們還需要一個(gè)程序代碼發(fā)布系統(tǒng)。這個(gè)發(fā)布系統(tǒng)可以幫我們實(shí)現(xiàn)下面的目標(biāo):
1)生產(chǎn)環(huán)境的服務(wù)器以虛擬主機(jī)方式提供服務(wù),不需要開發(fā)人員介入維護(hù)和直接操作,提供發(fā)布系統(tǒng)可以實(shí)現(xiàn)不需要登陸服務(wù)器就能把程序分發(fā)到目標(biāo)服務(wù)器。
2)我們要實(shí)現(xiàn)內(nèi)部開發(fā)、內(nèi)部測試、生產(chǎn)環(huán)境測試、生產(chǎn)環(huán)境發(fā)布的4個(gè)開發(fā)階段的管理,發(fā)布系統(tǒng)可以介入各個(gè)階段的代碼發(fā)布。3)我們需要實(shí)現(xiàn)源代碼管理和版本控制,SVN可以實(shí)現(xiàn)該需求。這里面可以使用常用的工具Rsync,通過開發(fā)相應(yīng)的腳本工具實(shí)現(xiàn)服務(wù)器集群間代碼同步分發(fā)。
大型高性能網(wǎng)站的十項(xiàng)規(guī)則
見過多種不同類型的網(wǎng)站和系統(tǒng),有好也有差。其中有些系統(tǒng)擁有良好的服務(wù)器/網(wǎng)絡(luò)架構(gòu),并且進(jìn)行了合理的調(diào)整和監(jiān)控;然而一般的系統(tǒng)都會有安全和性能上的問題,不能良好運(yùn)行,也無法變得更流行。
在中國,開源的LAMP棧是最流行的網(wǎng)絡(luò)架構(gòu),它使用PHP開發(fā),運(yùn)行在Apache服務(wù)器上,以MySQL作為數(shù)據(jù)庫,所有這些都運(yùn)行在Linux上。它是個(gè)可靠的平臺,運(yùn)行良好,是現(xiàn)在全球最流行的Internet系統(tǒng)架構(gòu)。然而,我們很難對其規(guī)模進(jìn)行正確的擴(kuò)展并保持安全性,因?yàn)槊總(gè)應(yīng)用層都有其自身的問題、缺陷和最佳實(shí)踐。我們的工作就是幫助企業(yè)用最低的操作成本來創(chuàng)建并運(yùn)行高性能的、可伸縮的、安全的系統(tǒng),因此對于這類問題我們有很豐富的經(jīng)驗(yàn)。
當(dāng)前的實(shí)際情況是,很多網(wǎng)站都是由開發(fā)人員快速而廉價(jià)地創(chuàng)建,通常沒有任何IT人員或者經(jīng)理,只是由程序員來管理系統(tǒng)。造成的結(jié)果是,雖然花費(fèi)很低的成本網(wǎng)站就可以開始運(yùn)行,但是當(dāng)擁有大量用戶、需要擴(kuò)展規(guī)模的時(shí)候,通常就會面臨真正的問題。畢竟,中國擁有三億八千萬的Internet用戶,如果其中的0.01%訪問這個(gè)站點(diǎn),就很容易引發(fā)25萬~50萬的頁面訪問量。這些問題在各個(gè)級別上都會產(chǎn)生,下面總結(jié)的規(guī)則是對最一般的問題進(jìn)行概述,并且說明為什么這些規(guī)則如此重要,以及最好采用什么方法來修正它們。遵循這些建議的站點(diǎn)會提高它的可伸縮性、安全性以及操作上的穩(wěn)定性。
使用合適的會話管理
第一個(gè)想到的擴(kuò)展系統(tǒng)的方法就是添加更多硬件。例如,使用兩臺服務(wù)器而不是一臺。這聽著合理,但會產(chǎn)生潛在問題:會話管理。這對Java程序來說是很嚴(yán)重的問題,在PHP中也會產(chǎn)生可延展性問題,對于數(shù)據(jù)庫的負(fù)載尤其如此。會話被定義為單獨(dú)的最終用戶登錄或者連接一段時(shí)間,其中通常會包含多個(gè)TCP/IP的HTTP連接、幾個(gè)Web頁面,通常還包括幾十個(gè)甚至上百個(gè)頁面元素,如框架、菜單、Ajax更新等。所有這些HTTP請求都需要知道用戶是誰,才能滿足安全的要求,并向用戶傳送適當(dāng)?shù)膬?nèi)容,因?yàn)檫@些都是會話的組成部分。通常每個(gè)會話都會包括相互關(guān)聯(lián)的會話數(shù)據(jù),如用戶名、用戶ID、歷史、購物車、統(tǒng)計(jì)資料等等信息。
問題在于,在有兩臺Web服務(wù)器和多個(gè)HTTP連接的情況下,用戶流量會在兩臺服務(wù)器之間分配和移動,服務(wù)器很難知道用戶是誰,并對所有數(shù)據(jù)進(jìn)行跟蹤,因?yàn)槊總(gè)頁面或者頁面的組成部分都可能來自不同的服務(wù)器。在PHP中,通常是這樣解決的,在第一次連接或登錄的時(shí)候就創(chuàng)建一個(gè)會話ID并將其放在Cookie中,然后這個(gè)Cookie會和每個(gè)HTTP請求一起發(fā)送。這樣做帶來一個(gè)問題,接下來每段PHP腳本都需要基于ID來查找會話數(shù)據(jù)。由于PHP無法在執(zhí)行過程之間保持狀態(tài)(這與Java不同),這個(gè)會話數(shù)據(jù)需要存儲在某個(gè)地方,通常是在數(shù)據(jù)庫中。但是,如果復(fù)雜的頁面需要在每個(gè)頁面載入過程中對其進(jìn)行十次查找(這是經(jīng)常要做的),那就意味著每個(gè)頁面都要執(zhí)行10次SQL查詢,這會導(dǎo)致數(shù)據(jù)庫上很大的負(fù)載。
在前面所舉的中國Internet用戶0.01%的例子中,可能很容易在每秒內(nèi)僅僅為了管理會話就生成上百個(gè)查詢。解決方法是一直使用位于Cookie中的會話ID,并且使用像Memcached之類的服務(wù)來緩存會話數(shù)據(jù)以獲得高性能。
還要注意其中存在安全性的問題,因?yàn)楹诳涂梢詡卧炝硪粋(gè)用戶的會話ID,這是很容易找到或看到的,特別是在公用的Wi-Fi中。解決方法是對會話ID進(jìn)行恰當(dāng)?shù)募用芑蛘吆灻,并將其與時(shí)間區(qū)間、IP地址以及其他關(guān)鍵信息像瀏覽器或者其他細(xì)節(jié)相綁定。在Internet上有很多不錯的關(guān)于良好的會話管理的例子,你可以根據(jù)需要找到最適合的。
總是要考慮安全性
盡管編寫像防止SQL注入和登錄安全之類的代碼涉及很多安全問題,但不幸的是,幾乎沒有人考慮過安全性,而那些考慮到的人也沒有對其進(jìn)行很好地理解。而本文要關(guān)注的是操作性的系統(tǒng)安全。對于這類安全,我們的焦點(diǎn)集中在三個(gè)安全領(lǐng)域:防火墻、運(yùn)行的用戶以及文件訪問權(quán)限。
除了配置專門的硬件防火墻(像Cisco的ASA)之外,所有服務(wù)器都還應(yīng)該運(yùn)行像Iptables之類的防火墻,它會保護(hù)服務(wù)器免受其他威脅和攻擊。這些威脅和攻擊可能來自公共的Internet、其他服務(wù)器或本地服務(wù)器,也包括使用VPN或者SSH通道的開發(fā)和操作人員。我們僅對指定的IP開放確實(shí)需要的端口。Iptables可能會很復(fù)雜,但是有很多不錯的模板,我們通?梢允褂盟鼈儊韼椭蛻魟(chuàng)建Iptables。例如,默認(rèn)的RedHat或者CentOS防火墻的配置說明只有10行,顯然并不實(shí)用。我們最佳實(shí)踐的Iptables配置大概有5頁,這其中包含了Linux所能提供的最高級的安全防范。
所有公用的服務(wù),都應(yīng)該運(yùn)行在專門的用戶下,如Apache。切記永遠(yuǎn)都不要使用Root用戶運(yùn)行,因?yàn)檫@會讓任何闖入到Apache的用戶接管整個(gè)服務(wù)器。如果Apache只是運(yùn)行在Apache用戶下或者運(yùn)行在Nobody下,那么闖入Apache就不是一件容易的事情了。
Web服務(wù)器運(yùn)行或者服務(wù)的文件(像.php和.html文件)對于Web服務(wù)器的用戶應(yīng)該是不可寫的。這意味著Apache或者Nginx用戶不應(yīng)該擁有Web目錄的寫權(quán)限。有很多方法都可以做到這一點(diǎn),而最簡單的就是將這些文件為其他用戶所有,然后讓Apache/Nginx等用戶歸屬于能夠使用640權(quán)限讀取文件的組中。這會防范幾乎所有的黑客和針對頁面的攻擊。此外,永遠(yuǎn)不要使用Ftp來上傳文件,特別是在公用的Wi-Fi環(huán)境中,因?yàn)樵谄渲泻诳秃苋菀妆I取用戶名和密碼。取而代之的是使用Sftp會更加安全。另外,每個(gè)雇員都應(yīng)該擁有自己的用戶ID和隨機(jī)密碼。
使用標(biāo)準(zhǔn)的路徑和安裝配置
一個(gè)令人討厭的部署問題是,開發(fā)者很少考慮他們的軟件會被部署到生產(chǎn)Web服務(wù)器的什么位置,以及如何部署。我們看到過許多大型的系統(tǒng)將它們的PHP代碼部署在/home/xiaofeng或者/web/code路徑下。事實(shí)上,這兩個(gè)路徑都是非常不標(biāo)準(zhǔn)的,并且會帶來操作和安全性的問題。當(dāng)這些系統(tǒng)從開發(fā)環(huán)境轉(zhuǎn)移到測試環(huán)境再到生產(chǎn)環(huán)境中時(shí),因?yàn)槊總(gè)安裝配置都是非標(biāo)準(zhǔn)的,所以經(jīng)常會出現(xiàn)問題,這時(shí)就需要開發(fā)者調(diào)整才能夠正常工作。
你應(yīng)該總是使用標(biāo)準(zhǔn)的安裝包和二進(jìn)制文件來安裝像Apache之類的服務(wù)器。不要從源代碼編譯或者安裝Tarball,因?yàn)檫@會導(dǎo)致長期穩(wěn)定性和管理上的問題,另外在服務(wù)器上安裝多個(gè)不同的版本也會造成混淆。
Web站點(diǎn)應(yīng)該總是在指定的平臺和Linux發(fā)布的標(biāo)準(zhǔn)路徑下進(jìn)行測試和部署,像RedHat或者CentOS下的/var/路徑。這有助于對系統(tǒng)進(jìn)行有效的權(quán)限管理、備份、配置、監(jiān)控以及其他操作。
Web服務(wù)器的日志應(yīng)該存放在/var/logs或者/var/logs/app_name下,而不應(yīng)該位于主代碼區(qū)域。這樣做的原因不僅僅是因?yàn)檫@些標(biāo)準(zhǔn)的路徑很重要,更應(yīng)該關(guān)注的是,恰當(dāng)?shù)嘏渲梅⻊?wù)器會將/var配置為分離的文件系統(tǒng)。如果應(yīng)用程序突然寫入了大量日志并占用所有磁盤空間,由于我們做了以上的配置就不會導(dǎo)致系統(tǒng)崩潰,或者其他嚴(yán)重的問題。如果日志位于其他位置,就可能會產(chǎn)生問題?偸鞘褂萌罩
在Web系統(tǒng)中做多少日志都不為過。所有系統(tǒng)都應(yīng)該將重要的數(shù)據(jù)寫入到日志中,不管是它們自己的日志還是系統(tǒng)的Syslog。Cron的Job以及其他Shell腳本或者C語言的程序,對日志都有相應(yīng)標(biāo)準(zhǔn)以及簡單的函數(shù)。在Shell腳本中,只需要使用Logger命令就可以實(shí)現(xiàn)日志的寫入。在腳本啟動/停止、重要的腳本執(zhí)行以及實(shí)時(shí)數(shù)據(jù)產(chǎn)生的情況下都要執(zhí)行寫入日志操作。這樣出現(xiàn)問題的時(shí)候,查看主要的系統(tǒng)日志就可以很容易地看到發(fā)生了什么。
大型系統(tǒng)經(jīng)常會使用專門的工具如Local5來記錄日志,并配置Syslog或者Syslog-ng來將其存放在單獨(dú)的文件中,這樣會更容易使用。需要注意的是,Syslog工具和Logger(以及任何Syslog調(diào)用)默認(rèn)優(yōu)先使用user.notice,如有必要,你可以對其進(jìn)行調(diào)整。一個(gè)好的系統(tǒng)會對程序進(jìn)行配置,用來打開或者關(guān)閉日志,并可以選擇在每模塊或者功能的級別上應(yīng)用不同級別的日志。這使得我們可以記錄非常詳細(xì)和強(qiáng)大的日志,用來分析和調(diào)試在生產(chǎn)操作中所發(fā)生的問題。
大型高性能網(wǎng)站的十項(xiàng)規(guī)則
使用良好的數(shù)據(jù)庫設(shè)計(jì)和SQL
在任何系統(tǒng)中,數(shù)據(jù)庫通常是最大的性能瓶頸。而影響數(shù)據(jù)庫性能的最大兩個(gè)問題是數(shù)據(jù)庫設(shè)計(jì)和SQL代碼質(zhì)量。很多系統(tǒng)都擁有良好的或者至少是可用的數(shù)據(jù)庫設(shè)計(jì),但由于沒有經(jīng)過適當(dāng)?shù)男阅軠y試,SQL代碼質(zhì)量通常都會很差。這樣的SQL代碼在開發(fā)環(huán)境中可能運(yùn)行很快,因?yàn)槠渲兄挥行?shù)據(jù)集和最小的負(fù)載。但是當(dāng)成千上萬的用戶同時(shí)讀取數(shù)據(jù)庫中上百萬條記錄的時(shí)候,它就很可能會崩潰。
不幸的是,這些問題一開始并不明顯,直到系統(tǒng)增大、突然開始崩潰的時(shí)候才會顯現(xiàn)出來。在增大的過程中,數(shù)據(jù)庫系統(tǒng)看起來運(yùn)行得很快(因?yàn)閿?shù)據(jù)都位于內(nèi)存中,而且很少有并發(fā)的查詢),并且對用戶的響應(yīng)也很快,但實(shí)際上它的內(nèi)部運(yùn)行效率很低。這并不重要,我們關(guān)注的是在系統(tǒng)增大并遇到性能問題之前找到這些問題并加以解決。關(guān)于這個(gè)問題有很多不錯的書和站點(diǎn)進(jìn)行了解析,其中的關(guān)鍵工具包括慢查詢?nèi)罩、INNODB狀態(tài)系統(tǒng),以及描述當(dāng)前性能的MySQL統(tǒng)計(jì)信息。我們見到過很多系統(tǒng)每秒會讀取500,000條數(shù)據(jù),這是出現(xiàn)SQL問題的明顯預(yù)兆,但公司往往對其一無所知直到服務(wù)器開始崩潰。
MySQL系統(tǒng)應(yīng)該對所有數(shù)據(jù)使用INNODB存儲引擎,因?yàn)镮NNODB與之前的MyISAM相比,運(yùn)行得更快、更穩(wěn)定,并且管理性能和備份工作也更加容易和快捷。在主配置文件中,INNODB應(yīng)該被設(shè)置為默認(rèn)的數(shù)據(jù)庫引擎,并且系統(tǒng)應(yīng)該不時(shí)地進(jìn)行檢查,看是否意外創(chuàng)建了MyISAM的表?傄獡碛辛己玫腄B配置和備份
很多公司都沒有良好的備份機(jī)制,也不知道如何恰當(dāng)?shù)赝瓿蛇@項(xiàng)工作。MySQL的Dump是不夠的,因?yàn)樽詈玫膫浞莘椒ㄊ鞘褂肔VM快照和INNODB對系統(tǒng)進(jìn)行熱備份,從而得到超快的速度和超高的可靠性。
另外,在將所有備份文件從服務(wù)器上轉(zhuǎn)移出來之前要進(jìn)行壓縮和加密。另外還要確保擁有設(shè)計(jì)合理的MySQL配置。MySQL默認(rèn)安裝使用說明中只有5~10行關(guān)于配置的說明,這根本不適合開發(fā)使用。而我們提供給客戶的最佳實(shí)踐文檔足足有10頁那么長。文檔中大約有100種有用的關(guān)于安全、性能和穩(wěn)定性問題的設(shè)定,包括防止數(shù)據(jù)敗壞,其中很多設(shè)定都是非常重要的。使用讀/寫數(shù)據(jù)庫分離
隨著系統(tǒng)變得越來越龐大,特別是當(dāng)它們擁有很差的SQL時(shí),一臺數(shù)據(jù)庫服務(wù)器通常不足以處理負(fù)載。但是多個(gè)數(shù)據(jù)庫意味著重復(fù),除非你對數(shù)據(jù)進(jìn)行了分離。更一般地,這意味著建立主/從副本系統(tǒng),其中程序會對主庫編寫所有的Update、Insert和Delete變更語句,而所有Select的數(shù)據(jù)都讀取自從數(shù)據(jù)庫(或者多個(gè)從數(shù)據(jù)庫)。
盡管概念上很簡單,但是想要合理、精確地實(shí)現(xiàn)并不容易,這可能需要大量的代碼工作。因此,即便在開始時(shí)使用同一臺數(shù)據(jù)庫服務(wù)器,也要盡早計(jì)劃在PHP中使用分離的DB連接來進(jìn)行讀寫操作。如果正確地完成該項(xiàng)工作,那么系統(tǒng)就可以擴(kuò)展到2臺、3臺甚至12臺服務(wù)器,并具備高可用性和穩(wěn)定性。使用類似Memcached之類的數(shù)據(jù)庫緩存
即便有了好的數(shù)據(jù)庫設(shè)計(jì)、SQL和讀寫分離,大型的系統(tǒng)仍然需要更快的性能,特別是對會話狀態(tài)、好友列表以及BBS文字之類的東西。為了達(dá)到這個(gè)目的,我們可以使用像MemCached之類的數(shù)據(jù)緩存,它是一個(gè)高性能的簡單數(shù)據(jù)緩存,已經(jīng)被所有最大型的站點(diǎn)使用。但是要小心的是,不要100%依賴于一臺Memcache服務(wù)器來提高性能,因?yàn)槿绻桥_服務(wù)器崩潰了,就會破壞整個(gè)系統(tǒng)的性能。在這種情況下,應(yīng)該使用2~3臺Memcache服務(wù)器形成簇集架構(gòu),并且有選擇地包含一個(gè)緩存準(zhǔn)備過程,如果緩存服務(wù)器重啟,需要重新載入數(shù)據(jù),它能夠快速地載入緩存。
構(gòu)建測試和開發(fā)環(huán)境
很多公司只有開發(fā)者的桌面系統(tǒng)和他們的生產(chǎn)服務(wù)器。當(dāng)系統(tǒng)變得越來越大、越來越復(fù)雜時(shí),測試和管理代碼就會導(dǎo)致嚴(yán)重的問題。最佳的實(shí)踐是擁有兩個(gè)測試系統(tǒng),一個(gè)用于開發(fā)者的代碼和功能的整合測試,另一個(gè)要與生產(chǎn)環(huán)境完全一致,從而更容易向生產(chǎn)環(huán)境平滑地過渡。幸運(yùn)的是,現(xiàn)在使用云計(jì)算(或者私有云)可以輕松達(dá)到這一點(diǎn)。一個(gè)5~10臺服務(wù)器的生產(chǎn)環(huán)境,可以很容易地在辦公室或者IDC中使用一臺服務(wù)器來復(fù)制,從而用于測試,而這臺服務(wù)器我們可以用于多個(gè)客戶的項(xiàng)目。
使用版本控制
最后,要對一切使用版本控制,包括測試和生產(chǎn)環(huán)境的部署。很多開發(fā)者都使用SVN或者類似的方法。在理想狀態(tài)下,這些方法可以被用于所有代碼、腳本、HTML、圖片、配置、文檔和測試。版本控制應(yīng)該是代碼轉(zhuǎn)移到測試環(huán)境的必經(jīng)之路,而不是簡單地復(fù)制或者使用tar文件,因?yàn)檫@二者都是不可靠的。開發(fā)者應(yīng)該將所有一切都簽入,打上標(biāo)簽,然后將它們簽出到測試系統(tǒng)。如果所有都沒問題,那么它們會將該版本簽出到生產(chǎn)環(huán)境?偨Y(jié)
不管是在開發(fā)還是在運(yùn)營過程中,創(chuàng)建可靠的高性能Web系統(tǒng)都有很多應(yīng)該注意的事項(xiàng)。本文試圖從可操作性和可靠性的角度討論最重要的幾點(diǎn)。當(dāng)你構(gòu)建和管理站點(diǎn)的時(shí)候,請不要忘了這些重要的問題。遵循這些規(guī)則會有助于確保系統(tǒng)長久、良好地運(yùn)行。作者簡介:
SteveMushero,ChinaNetCloud公司聯(lián)合創(chuàng)始人、CEO兼CTO,擁有全球20多年的技術(shù)管理經(jīng)驗(yàn)。曾擔(dān)任土豆網(wǎng)、Intermind和AdvancedManagementSystems等多家企業(yè)CTO
友情提示:本文中關(guān)于《大型門戶網(wǎng)站架構(gòu)心得》給出的范例僅供您參考拓展思維使用,大型門戶網(wǎng)站架構(gòu)心得:該篇文章建議您自主創(chuàng)作。
來源:網(wǎng)絡(luò)整理 免責(zé)聲明:本文僅限學(xué)習(xí)分享,如產(chǎn)生版權(quán)問題,請聯(lián)系我們及時(shí)刪除。