【轉】一份發表於2010年左右的百萬級訪問量網站的技術準備工做

  注:本篇從InfoQ上轉載而來,做者 劉志一,若有侵權請聯繫本博主,會立馬刪除。前端

  本文是5年前發佈在InfoQ網站的一篇文章,如今看起來,雖然部分工具已通過時,但做者的思路以及部分方案仍是有不少能夠參考的地方。程序員

  5年,IT領域已經發生了翻天覆地的變化,不妨看看這篇文章,想一想5年時間,哪些工具或者框架已經被淘汰,哪些當初不肯定的概念,到如今已經落地。web

  若是你有你的感悟,歡迎私信我(微信greenguolei),咱們一塊兒聊聊,這5年,IT領域發生了哪些有意思的事情。數據庫

  當今從純網站技術上來講,由於開源模式的發展,如今建一個小網站已經很簡單也很便宜,因此不少人都把創業方向定位在互聯網應用。這些人裏大多數不是很懂技術,或者不是那麼精通,而網站開發維護方面的知識又很分散,學習成本過高,因此這篇文章將這些知識點結合起來,系統的來講,一個從日幾千訪問的小小網站,到日訪問一兩百萬的小網站,中間可能會產生什麼問題,以及怎麼才能在一開始作足工做盡可能避免這些問題。編程

  你的網站由於努力經營,訪問量逐漸升高,在升高的過程當中,問題也可能開始顯現了。由於帶寬的增長、硬件的擴展、人員的擴張所帶來的成本提升是顯而易見的,而還有至關大的一部分紅本是由於代碼重構、架構重構,甚至底層開發語言更換引發的,最壞的狀況就是數據丟失,全部努力付之一炬。這類成本支出大多數在一開始就能夠避免,先打好基礎,日後能夠省不少精力,少操不少心。ubuntu

  對於不一樣的初期投資成本,技術路線的選擇是不一樣的。這裏假設網站剛剛只是一個構想,計劃第一年服務器硬件帶寬投入5萬左右。對於這個資金額度,有不少種方案可選擇,例如租用虛擬主機、租用單獨服務器,或者流行的私有云,或者託管服務器。前兩種選擇,網站發展到必定規模時需遷移,那時再重作規劃顯然影響更大。服務器託管由於配置自主、能徹底掌握控制權,因此有必定規模的網站基本都是這種模式。採用本身託管服務器的網站,一開始要注意如下幾點。後端

1、開發語言

  通常來講,技術人員(程序員)都是根據本身技術背景選擇本身最熟悉的語言,不過不可能永遠是一我的寫程序,因此在語言的選擇上還要是要費些心思。首先明確一點,不管用什麼語言,最終代碼質量是看管理,所以咱們從前期開發成本分析。如今國內流行的適用於網站的語言,大概有Java、PHP、.NET、Python、Ruby這五大陣營。Python和Ruby由於在國內流行的比較晚,如今人員仍是相對難招一些。.NET平臺的人相對多,可是到後期須要解決性能問題時,對人員技能的要求比較高。剩餘的Java、PHP用人能夠說是最多的。Java和PHP沒法從語言層面作比較,但對於初期,應用幾乎都是靠前端支撐的網站來講,PHP入門簡單、編寫快速,優點相對大一點。至於後端例如行爲分析、銀行接口、異步消息處理等,等真正須要時,就要根據不一樣業務需求來選擇不一樣語言了。瀏覽器

2、代碼版本管理

  稍微有點規模的網站就須要使用代碼版本管理了。代碼版本管理兩點最大的好處,一是方便協同工做,二是有歷史記錄可查詢比較。代碼版本管理軟件有不少,CVS/SVN/hg/Git等,目前國內都比較流行,其中SVN的普及度仍是很高的(幾年前的文章,如今固然是Git了)。緩存

  假設選了SVN,那麼有幾點考慮。一是採用什麼樹結構。初期可能只有一條主幹,日後就須要創建分支,例如一條開發分支,一條上線分支,再日後,可能要每一個小組一個分支。建議一開始人少時選擇兩條分支,開發和線上,每一個功能本地測試無誤後提交到開發分支,最後統一測試,能夠上線時合併到上線分支。若是每人都建本身的分支,合併時會浪費很大精力,對於幾乎天天都要修改幾回的WEB應用來講,所費時間太多。安全

  向服務器部署代碼,能夠手工部署也能夠自動部署。手工部署相對簡單,通常可直接在服務器上svn update,或者找個新目錄svn checkout,再把web root給ln -s過去。應用越複雜,部署越複雜,沒有什麼統一標準,只是別再用ftp上傳那種形式,一是上傳時文件引用不一致錯誤率增長,二是很容易出現開發人員的版本跟線上版本不一致,致使原本想改個錯字結果變成回滾。若是有多臺服務器仍是建議自動部署,更換代碼的機器從當前服務池中臨時撤出,更新完畢後再從新加入。

3、服務器硬件

  在各個機房裏,靠一臺服務器孤獨支撐的網站數不清,但若是資金稍微充足,建議至少三臺的標準配置,分別用做web處理、數據庫、備份。web服務器至少要8G內存,雙sata raid1,若是經濟稍微寬鬆,或靜態文件或圖片多,則15k sas raid10。數據庫至少16G內存,15k sas raid 10。備份服務器最好跟數據庫服務器同等配置。硬件能夠上整套品牌,也能夠兼容機,也能夠半品牌半組裝,取決於經濟能力。固然,這是典型的搭配,有些類型應用的性能瓶頸首先出如今web上,那種狀況就要單獨分析了。

  Web服務器能夠既跑程序又當內存緩存,數據庫服務器則只跑主數據庫(假如是MySQL的話),備份服務器所承擔就相對多一些,web配置、緩存配置、數據庫配置都要跟前兩臺一致,這樣WEB和數據庫任意一臺出問題,很容易就能夠將備份服務器切換過去臨時頂替,直到解決完問題。要注意,硬件是隨時可能壞掉的,特別是硬盤,因此寧肯WEB服務器跟數據庫服務器放在一塊兒,也必定不能省掉備份,備份必定要異機,而且有異步,電力故障、誤操做均可能致使一臺機器上的全部數據丟失。不少的開源備份方案可選擇,最簡單的就是rsync,寫crontab裏,定時同步。備份和切換,建議多作測試,選最安全最適合業務的,而且儘量異地備份。

4、機房

  三種機房儘可能不要選:聯通訪問特別慢的電信機房、電信訪問特別慢的聯通機房、電信聯通訪問特別慢的移動或鐵通機房。機房要儘量多的實地參觀,多測試,找個網絡質量好,管理嚴格的機房。機房能夠說是很是重要,直接關係到網站訪問速度,網站訪問速度直接關係到用戶體驗,訪問速度很慢的網站,很難得到用戶青睞。

5、架構

  在大方向上,被熟知的架構是web負載均衡+數據庫主從+緩存+分佈式存儲+隊列。在一開始,按照可擴展的原則設計和編程就能夠。只是要多考慮緩存失效時的雪崩效應、主從同步的數據一致性和時間差、隊列的穩定性和失敗後的重試策略、文件存儲的效率和備份方式等等意外狀況。緩存失效、數據庫複製中斷、隊列寫入錯誤、電源損壞,在實際運維中常常發生,若是不注意這些,出現問題時恢復期可能會超出預期很長時間。

6、服務器軟件

  操做系統Linux很流行。在沒有專業運維人員的狀況下,應傾向於擇使用的人多、社區活躍、配置方便、升級方便的發行版,例如RH系列、Debian、ubuntu server等,硬件和操做系統要一塊兒選擇,看是否有適合的驅動,若是肯定用某種商業軟件或解決方案,也要提早知曉其對哪一種操做系統支持最佳。web服務器方面,Apache、Nginx、Lighttpd三大系列中,Apache佔有量仍是最大,可是想把性能調教好仍是須要很專業的,Nginx和Lighttpd在不須要太多調整的狀況下能夠達到一個比較不錯的性能。不管選擇什麼軟件,除非改過這些軟件或你的程序真的不兼容新版本,不然儘可能版本越新越好,版本新,意味着新特性增多、BUG減小、性能增長。

  一個典型的PHP網站,基本上大多數人都沒改過任何服務器軟件源代碼,絕大多數狀況是能平穩的升級到新版本的。相似於JDK5到 JDK 6,Python2到Python3這類變更比較大的升級仍是比較少見的。看看ChangeLog,看看升級說明,結合本身狀況評估測試一下,越早升級越好,升級的越晚,所花費的成本越高。對於軟件包,儘可能使用發行版內置的包管理工具,沒有特殊要求時不建議本身編譯,那樣對未來運維不利。

7、數據庫

  幾乎全部操做最後都要落到數據庫身上,它又最難擴展(存儲也挺難)。數據庫常見的擴展方法有複製、分片,設計時要考慮到每種應用的數據如何複製、分片,固然這種考慮通常會推遲到技術設計時期。在初期進行數據庫結構設計時,要根據不一樣的業務類型和增加量預期來考慮是否要分庫、分區,而且儘可能不要使用聯合查詢、不使用自增ID以方便分片。複製延時問題、主從數據庫數據一致性問題,能夠本身寫或者用已有的運維工具進行檢測。

  用存儲過程是比較難擴展的,這種情形多發生於傳統C/S,特別是OA系統轉換過來的開發人員。低成本網站不是一兩臺小型機跑一個數據庫處理全部業務的模式,是機海做戰。方便水平擴展比那點預分析時間和網絡傳輸流量要重要的多的多。

  另外,如今流行一種概念叫NoSQL,能夠理解爲非傳統關係型數據庫。實際應用中,網站有着愈來愈多的密集寫操做、上億的簡單關係數據讀取、熱備等,這都不是傳統關係數據庫所擅長的,因而就產生了不少非關係型數據庫,好比Redis/TC&TT/MongoDB/Memcached等,在測試中,這些幾乎都達到了每秒至少一萬次的寫操做,內存型的甚至5萬以上。在設計時,可根據業務特色和性能要求來選擇是否使用這類數據庫。例如MongoDB,幾句配置就能夠組建一個複製+自動分片+failover的環境,文檔化的存儲也簡化了傳統設計庫結構再開發的模式。可是當你決定採用一項技術時,必定要真正瞭解其優劣,例如可能你所選擇的技術並不能支持你所須要的事務和數據一致性要求。

8、文件存儲

  存儲的分佈幾乎跟數據庫擴展同樣困難,不過只有百萬的PV的狀況下,磁盤IO方面通常不會成大問題,一兩臺採用SATA作條帶RAID的機器能夠應付,反而是本身作異步備份比較複雜,由於小文件多。若是隻有一臺機器作存儲,能夠作簡單的優化,例如放最小縮略圖的分區和放中等縮略圖的分區,根據平均大小調整一下塊大小。存儲要規劃好目錄結構,不然文件增多後維護起來複雜,也不利於擴展。同時還要考慮未來擴容,例如採用LVM,或者把文件根據不一樣規則散列到不一樣機器。磁盤IO繁重的狀況下更容易出現故障,因此要作好備份,若發現有盤壞掉,要立刻行動更換,不少人的硬盤都是壞了一塊以後,連續不斷的壞下去。

  爲了未來圖片走cdn作準備,一開始最好就將圖片的域名分開,且不用主域名。由於不少網站都將cookie設置到了.domain.ltd,若是圖片也在這個域名下,極可能由於cookie而形成緩存失效,而且佔多餘流量,還可能由於瀏覽器併發線程限制形成訪問緩慢。

9、程序

  必定硬件條件下,應用能承載多少訪問量,很大一部分也取決於程序如何寫。程序寫的很差,可能一萬的訪問都承載不了,寫的好,可能一兩臺機器就能承擔幾百萬PV。越是複雜、數據實時性要求越高的應用,優化起來越難,但對普通網站有一個統一的思路,就是儘可能向前端優化、減小數據庫操做、減小磁盤IO。向前端優化指的是,在不影響功能和體驗的狀況下,能在瀏覽器執行的不要在服務端執行,能在緩存服務器上直接返回的不要到應用服務器,程序能直接取得的結果不要到外部取得,本機內能取得的數據不要到遠程取,內存能取到的不要到磁盤取,緩存中有的不要去數據庫查詢。減小數據庫操做指減小更新次數、緩存結果減小查詢次數、將數據庫執行的操做盡量的讓你的程序完成(例如join查詢),減小磁盤IO指儘可能不使用文件系統做爲緩存、減小讀寫文件次數等。程序優化永遠要優化慢的部分,換語法是沒法「優化」的。

  然而編程時不該該把重點放在優化上,應該關注擴展性。當今的WEB應用,需求變化很是之快,適應多種需求的架構是不存在的,咱們的擴展性就要把要點放在跟底層交互的架構上,例如持久化數據的存取規則、緩存的存取規則等,還有一些共用服務,例如用戶信息等。先把不變的部分作完善,剩下的部分就很容易將精力放在業務邏輯上面了。

相關文章
相關標籤/搜索