天天看點

網站架構的逐漸優化演變

一:建站之初

    • *

建站之初,站點流量非常小,可能低于十萬級别。這意味着,平均每秒鐘也就幾次通路。請求量比較低,資料量比較小,代碼量也比較小,幾個工程師,很短的時間搭起這樣的系統,甚至沒有考慮“架構”的問題。

站點架構特點是“ALL-IN-ONE”:

這是一個單機系統,所有的站點、資料庫、檔案都部署在一台伺服器上。工程師每天的核心工作是CURD,浏覽器端傳過來一些資料,解析GET/POST/COOKIE中傳過來的資料,拼裝成一些CURD的sql語句通路資料庫,資料庫傳回資料,拼裝成頁面,傳回浏覽器。相信很多創業團隊的工程師,初期做的也是類似的工作。

比如:微軟技術體系這條路:Windows、iis、SQL-Sever、C#

推薦選擇LAMP體系。

為什麼選擇LAMP?

LAMP無須編譯,釋出快速,功能強大,社群活躍,從前端+後端+資料庫通路+業務邏輯處理全部可以搞定,并且開源免費,公司做大了也不會有人上門收錢(不少公司吃過虧)。現在大家如果再創業,強烈建議使用LAMP。

初創階段,工程師面臨的主要問題:寫CURD的sql語句很容易出錯。

我們在這個階段引進DAO和ORM,讓工程師們不再直接面對CURD的sql語句,而是面對他們比較擅長的面向對象開發,極大的提高了編碼效率,降低了出錯率。

二:流量增加,資料庫成為瓶頸

随着流量越來越大,老闆不隻要求“有一個可以看見的站點”,他希望網站能夠正常通路,當然速度快點就更好了。

而此時系統面臨問題是:流量的高峰期容易當機,大量的請求會壓到資料庫上,資料庫成為新的瓶頸,人多并行通路時站點非常卡。這時,我們的機器數量也從一台變成了多台,我們的系統成了所謂的(僞)“分布式架構”:

我們使用了一些常見優化手段:

  • (1)動靜分離,動态的頁面通過Web-Server通路,靜态的檔案例如圖檔就放到單獨的檔案伺服器上;
  • (2)讀寫分離,将落到資料庫上的讀寫請求分派到不同的資料庫伺服器上;

網際網路絕大部分的業務場景,都是讀多寫少。對通路量大的系統來說,絕大部分使用者的需求是通路資訊,搜尋資訊,隻有少數的使用者發貼。此時讀取性能容易成為瓶頸,那麼如何擴充整個站點架構的讀性能呢?常用的方法是主從同步,增加從庫。我們原來隻有一個讀資料庫,現在有多個讀資料庫,就提高了讀性能。

在這個階段,系統的主要沖突為“站點耦合+讀寫延時”,如何解決這兩個問題的呢?

第一個問題是站點耦合。對釋出資訊的系統而言,典型業務場景是:類别聚合的首頁,釋出資訊的釋出頁,資訊聚合的清單頁,文章内容的詳細頁,原來這些系統都耦合在一個站點中,出現問題的時候,整個系統都會受到影響。

第二個問題是讀寫延時。資料庫做了主從同步和讀寫分離之後,讀寫庫之間資料的同步有一個延時,資料庫資料量越大,從庫越多時,延時越明顯。對應到業務,有使用者發文章,馬上去搜尋可能搜尋不到(着急的使用者會再次釋出相同的文章)。

要解決耦合的問題,最先想到的是針對核心業務做切分,工程師根據業務切分對系統也進行切分:我們将業務垂直拆分成了首頁、釋出頁、清單頁和詳情頁。

另外,我們在資料庫層面也進行了垂直拆分,将單庫資料量降下來,讓讀寫延時得到緩解。

同時,還使用了這些技術來優化系統和提高研發效率:

  • (1)對動态資源和靜态資源進行拆分。對靜态資源我們使用了CDN服務,使用者就近通路,靜态資源的通路速度得到很明顯的提升;
  • (2)除此之外,我們還使用了MVC模式,擅長前端的工程師去做展示層,擅長業務邏輯的工程師就做控制層,擅長資料的工程師就做資料層,專人專用,研發效率和品質又進一步提高。

第三:全面轉型開源技術體系

流量越來越大,當流量達到百萬甚至千萬時,站點面臨一個很大的問題就是性能和成本的折衷。上文提到很多系統最初的技術選型是Windows,我們在這個階段做了一次脫胎換骨的技術轉型,全面轉向開源技術:

(1)作業系統轉型Linux

(2)資料庫轉型Mysql

(3)web伺服器轉型Tomcat

(4)開發語言轉向了Java

其實,很多網際網路公司在流量從小到大的過程中都經曆過類似的轉型,例如京東和淘寶。

随着使用者量的增加,對站點可用性要求也越來越高,機器數也從最開始的幾台上升到幾百台。那麼如何提供保證整個系統的可用性呢?首先,我們在業務層做了進一步的垂直拆分,同時引入了Cache,如下圖所示:

在架構上,我們抽象了一個相對獨立的服務層,所有資料的通路都通過這個服務層統一來管理,上遊業務線就像調用本地函數一樣,通過RPC的架構來調用這個服務擷取資料,服務層對上遊屏蔽底層資料庫與緩存的複雜性。

除此之外,為了保證站點的高可用,我們使用了反向代理。

什麼是代理?代理就是代表使用者通路xxoo站點。

什麼是反向代理?反向代理代表的是自己的網站,使用者不用關注通路是你網站的哪台伺服器,由反向代理來代表你的網站。你的網站通過反向代理,DNS輪詢, LVS等技術,來保證接入層的高可用性。

另外,為了保證服務層和資料層的高可用,我們采用了備援的方法,單點服務不可用,我們就備援服務,單點資料不可用,我們就備援資料。

這個階段你的伺服器進入了一個業務高速爆發期,短期内衍生出非常多的業務站點和服務。新增站點、新增服務每次都會做一些重複的事情,例如線程模型,消息隊列,參數解析等等

這個階段,為了進一步解耦系統,我們引入了配置中心、柔性服務和消息總線。

引入配置中心,業務要通路任何一個服務,不需要在本地的配置檔案中配置服務的ip list,而隻需要通路配置中心。這種方式的擴充性非常好,如果有機器要下線,配置中心會反向通知上遊訂閱方,而不需要更新本地配置檔案。

柔性服務是指當流量增加的時候,自動的擴充服務和站點。

消息總線也是一種解耦上下遊“調用”關系常見的技術手段。

機器越來越多,此時很多系統層面的問題,靠“人肉”已經很難搞定,于是自動化變得越來越重要:自動化回歸、自動化測試、自動化運維、自動化監控等等等等。

最後補充一點,這個階段引入了不少智能化産品,比如智能推薦,主動推薦一些相關的資料,以增加系統的PV;智能廣告,通過一些智能的政策,讓使用者對廣告的點選更多,增加同城的收入;智能搜尋,在搜尋的過程中加入一些智能的政策,提高使用者的點選率,以增加系統的PV。這些智能化産品的背後都由技術驅動。

四:進一步的挑戰

現在,系統的流量已經達到10億的量級,架構上我們規劃做一些什麼樣的事情呢,幾個方向:

(1)業務服務化

(2)多架構模式

(3)平台化

(4)...

五:小結

最後做一個簡單的總結,網站在不同的階段遇到的問題不一樣,而解決這些問題使用的技術也不一樣:

(1)流量小的時候,我們要提高開發效率,可以在早期要引入ORM,DAO;

(2)流量變大,可以使用動靜分離、讀寫分離、主從同步、垂直拆分、CDN、MVC等方式不斷提升網站的性能和研發效率;

(3)面對更大的流量時,通過垂直拆分、服務化、反向代理、開發架構(站點/服務)等等手段,可以不斷提升高可用(研發效率);

(4)在面對上億級的流量時,通過配置中心、柔性服務、消息總線、自動化(回歸,測試,運維,監控)來迎接新的挑戰;