58同城沈劍:好的架構是進化來的,不是設計來的

好的架構不是設計出來的而是演進出來的前端

對不少創業公司而言,在初期的時候,咱們很難在初期就預估到流量十倍之後、百倍之後、一千倍之後網站的架構會變成什麼樣。固然,若是在最初的時期,就設計一個千萬級併發的流量架構,那樣的話,成本是也是很是之高的,估計很難有公司會這樣作。git

因此,咱們主要來說架構是如何進行演化的。咱們在每一個階段,找到對應該階段網站架構所面臨的問題,而後在不斷解決這些問題的過程當中,整個戰略的架構就是在不斷的演進了。github

其實,在 58 同城創建之初,站點的流量很是小,可能也就是是十萬級別,這也就意味着,平均每秒鐘也就是幾回的訪問。此時網站架構的特色:請求量是比較低,數據量比較小,代碼量也比較小。可能找幾個工程師,很容易就作一個這樣的站點,根本沒什麼「架構」可言。數據庫

其實,這也是不少創業公司初期面臨的問題,最開始58同城的站點架構用一個詞歸納就是「ALL IN ONE」,以下圖所示:後端

58同城沈劍:好的架構是進化來的,不是設計來的

就像一個單機系統,全部的東西都部署在一臺機器上,包括站點、數據庫、文件等等。而工程師天天的核心工做就是 CURD,前端傳過來一些數據,而後業務邏輯層拼裝成一些 CURD 訪問數據庫,數據庫返回數據,數據拼裝成頁面,最終返回到瀏覽器。相信不少創業團隊,初期作的工做也是相似,天天寫代碼,寫 SQL、接口參數、訪問數據等等。瀏覽器

這裏須要說明一個問題,你們都知道目前 58 同城使用的是 Windows、iis、SQL-Sever、C# 這條路。如今不少創業公司可能就不會這麼作。58 同城爲何當時選擇了這條路?緣由是公司招聘的第一個工程師和第二個工程師只會這個,因此只能走這條路。緩存

若是能夠重來?那麼會選擇LAMP服務器

不少創業的同窗可能會想,若是咱們初期但願作一個產品的話,咱們應該使用什麼架構? 若是讓咱們重來,可能咱們如今會選 LAMP,爲何?首先是無須編譯,並且快速發佈功能強大,從前端到後端、數據庫訪問、業務邏輯處理等等所有能夠搞定,最重要的是由於開源產品,是徹底免 費的。若是使用 LAMP 搭建一個論壇,兩天的時間就很足夠了。因此,若是在創業初期,就儘可能不要再使用 Windows 的技術體系了。架構

58同城沈劍:好的架構是進化來的,不是設計來的

在這個階段 58 同城面臨的主要問題是什麼?其實就是招人。不少工程師可能都是再培訓學校裏培訓了3月就過來上班,因此他們寫 CURD 的話很容易出錯。當時,咱們引進了 DAO 和 ORM。雖然那些培訓了幾個月的工程師可能寫CURD不是特別的擅長,可是他們寫面向對象的一些程序引入了 DAO 和 ORM,讓他們再也不直接面對 CURD 語句,這樣就會相對容易一些。由於工程師比較擅長的是面向對象的數據,不是 CURD,因此咱們當時引入了 ORM,總的來講,若是你們如今的項目處於一個初期孵化的階段,DAO 和 ORM 可以極大的提升效率,並且能夠下降出錯的機率。併發

中等規模:流量跨過十萬的階段,數據庫成爲瓶頸

隨着 58 同城的高速增加,咱們很快跨越了十萬流量的階段。主要需求是什麼?網站可以正常訪問,固然速度更快點就行了。而此時系統面臨問題包括:在流量的高峯期容易 宕機,由於大量的請求會壓到數據庫上,因此數據庫成爲新的瓶頸,並且人多的時候,訪問速度會很慢。這時,咱們的機器數量也從一臺變成了多臺。如今的架構就 採用了分佈式,以下圖所示:

58同城沈劍:好的架構是進化來的,不是設計來的

首先,咱們使用了一些很是常見的技術,一方面是動靜分離,動態的頁面經過 Web-Servre 訪問,靜態的像圖片等就單獨放到了一些服務器上。另一點就是讀寫分離。其實,對 58 同城或者說絕大部分的站點而言,通常來講都是讀多寫少。對 58 同城來講,絕大部分用戶是訪問信息,只有不多的用戶過來發貼。那麼如何擴展整個站點架構的讀請求呢?經常使用的是主從同步,讀寫分離。咱們原來只有一個數據 庫,如今使用多個不一樣的數據庫提供服務,這樣的話,就擴展了讀寫,很快就解決了中等規模下數據訪問的問題。

在這個階段,系統的主要矛盾就是「站點耦合+讀寫延時」,58 同城是如何進行解耦,如何緩解延時呢?

對 58 同城而言,典型業務場景是主頁,發佈信息有發佈頁,信息聚合、標題聚合有列表頁,點開一個標題有詳細頁,而這些站點都是耦合在一個程序中的,或者說耦合在一個站點中的,當咱們有一個站點出現問題的時候,整個站點就會由於耦合一塊兒出問題。

58同城沈劍:好的架構是進化來的,不是設計來的

第二個問題,你們都知道作數據庫讀請求和寫請求,分佈在不一樣的數據庫上,這個時候若是再讀取可能讀到的是舊數據,由於讀寫有一個延時。若是有用戶發 帖子,立刻去找的話確定找不到,極可能帶來的後果就是陸續在發佈兩條信息,這就是一個很大的問題。尤爲是在請求量愈來愈大的時候,這個問題就更加突出。

在解決這些問題是,最早想到的是針對原來站點的核心業務作切分,而後工程師根據本身的站點和業務場景進行細分。首先,業務拆分是 58 同城最早嘗試的優化。咱們將業務垂直拆分紅了首頁和發佈頁。另外,在數據庫層面,咱們也隨之進行了拆分,將大數據量拆分紅一個個小的數據量。這樣,讀寫延 時就立刻獲得了緩解。尤爲是在代碼拆分紅了不一樣的層面以後,站點耦合也獲得了緩解,數據量加載速度也提高了不少。

58同城沈劍:好的架構是進化來的,不是設計來的

當時,還使用了一些技術,前面也提到了對動態資源和靜態資源進行拆分。其中,咱們對靜態資源使用了 CDN 服務,便於數據緩存和就近訪問,訪問速度獲得很明顯的提高。除此以外,咱們還使用了 MVC 模式,擅長前端的去作展現層,擅長協做邏輯的工程師就作 Contorller,擅長數據的人就負責數據,效率就會逐步的提升,最後就是負載均衡技術。

大流量:將整個 Windows 技術體系轉向了 Java 體系

流量愈來愈大,當流量超過一千多萬時,58 同城面對最大的問題就是性能和成本。此前,我提到58同城最初的技術選型是 Windows,應該是在 2006 年的時候,整個網站的性能變得很是之低。即便進行了業務拆分和一些優化,可是依然解決不了這個問題,因此咱們當時作了一個很是艱難的決定,就是轉型:將整 個 Windows 技術體系轉向了 Java 體系,這涵蓋了操做系統、數據庫等多個維度。

58同城沈劍:好的架構是進化來的,不是設計來的

其實,如今不少大的互聯網公司在流量從小到大的過程當中都經歷過轉型,包括京東、淘寶等等。對技術的要求愈來愈高,任何一個站點都不能掛,對站點的可用性要求也是愈來愈高。

就在這個時候,58 同城業務量也出現一個爆發期。因而咱們招聘了不少的工程師,你們一塊兒寫愈來愈多的站點,可是發現效率很低,常常作一些重複性的工做好比參數解析等等。同 時,業務之間相互依賴,不管是分類的子系統仍是信息的子系統,二手車業務、房產業務都要訪問用戶和信息等一些底層數據,代碼之間頻繁的溝通,效率也不可能 很高。

問題隨之而來,站點數愈來愈多,數據量愈來愈大,機器數從最開始的幾臺上升到幾百臺的級別。那麼如何提供整個架構的可用性呢?首先,在上層咱們進行了一些改進和優化,再作進一步的垂直拆分,同時咱們引入了 Cache,以下圖所示:

58同城沈劍:好的架構是進化來的,不是設計來的

在架構的改進上,咱們構建了一個相對獨立的服務層,這個服務層作的每一個業務線都會寫對應的代碼。若是用戶發出請求,就由這個服務層統一來管理,全部 的上游業務線就像調用本地函數同樣,經過 IDC 的框架來調用這個服務。整個用戶登陸先訪問 Cache,若是 Cache 變更了就直接返回,若是 Cache 不變更,就會訪問數據庫,這樣把數據庫的數據拿到本地再放回 Cache,再打回上一輪。如此一來,業務邏輯所有封裝在這個服務的上游管理,該業務邏輯只有服務層可以編寫代碼,而後由這個服務層集中管理、集中優化, 這樣就提升了效率。

58同城沈劍:好的架構是進化來的,不是設計來的

除此以外,爲了保證站點的高可用,咱們主要使用了反向代理技術。由於用戶而言,他主要爲了使用 58 同城的服務,他不關注訪問是58同城或者有十臺首頁的服務器。58 同城經過反向代理技術,經過 DNS 羣,經過 LVS 技術,來保證接入層的高可用性,同時還保證了服務層、站點層、數據層的高可用。另外,爲了保證高可用咱們常用冗餘的方法,不管是站點服務和數據服務都 可使用這種方式進行解決,一個站點不可用,咱們就換一個站點,一個數據庫不夠用,咱們就多加幾個。固然,數據冗餘也會帶來一些反作用,若是數據量更新的 話,那就須要將全部的「冗餘」都要進行更新。

58同城也作了一個圖片存儲系統,開始都是存儲在操做系統之上,隨着新增站點、新增服務,壓力就變得愈來愈大。因而,58 同城就自建了站點框架和服務框架,如今這兩個框架也已經開源(如何下降站點開發成本?https://github.com/58code/Argo 如何下降服務開發成本? https://github.com/58code/Gaea )只須要修改一些基本的配置就可使用了。

當架構變成「蜘蛛網」,人肉已很難搞定!

隨着用戶量、數據量併發量進一步的增加,58同城也拓展了不少的新業務,那麼對產品迭代速度要求就很是高,總體的架構對自動化的要求愈來愈高。

58同城沈劍:好的架構是進化來的,不是設計來的

爲了支撐業務的發展,技術團隊對架構作了進一步的解耦,另外就是引入了配置中心,若是要訪問任何一個服務,不會直接在本地的配置中留下一個服務,配 置中心告訴這個服務的特色,若是擴展的話,配置中心自動下達消息,若是有機器要下線的話,配置中心會反向經過發郵件的方式進行通知。

而柔性服務是指當流量增長的時候,自動的新增服務。能夠看到進一步解耦以後,有垂直業務、無線業務、集成業務等等,這些子系統之間都是經過配置中心相應之間發生關係的。

另外一點就是關於數據庫,當某一點成爲一個業務線重點的時候,咱們就會集中解決這個點的問題。最初期的時候每一個業務線都要訪問數據庫,訪問緩存,訪問 用戶數據,因而咱們把代碼集中的放到了服務層。如今數據量愈來愈大,你們都要作數據切分,每一個業務線都作切分,這個時候58同城的每一個頁面都面對這樣的痛 點,因而把這個痛點拿到集中的層面來解決。

最後一點就是效率矛盾,此時不少問題,靠「人肉」已經很難進行搞定了。這就須要自動化,包括迴歸、測試、運維、監控等等都要回歸到自動化。

這裏須要補充一點,就是在產品層面,咱們引入了智能化,好比說智能推薦,主動推薦一些相關的話題;智能廣告,經過一些智能的策略,讓用戶對廣告的點 擊更多,增長對 58 同城的收錄;智能搜索,在搜索的過程當中加入一些搜索的策略,能夠提升搜索的權重,也能夠增長 58 同城的 PV。固然,全部的自動化的產品背後都是由技術在驅動。

將來的挑戰

如今,58同城的流量已經突破的 10 億的量級,那麼架構上將來面臨哪些挑戰呢?一方面是無線化、移動化。另外一方面就是需求的變化,咱們必須加快迭代一些東西。若是擁有10億的流量,卻跑在一 億的架構上確定是不行的。將來,咱們會使用更多的並行計算、實時計算,若是能作到實時推薦,效果確定很是好,這也是咱們的挑戰。最後一點,58同城如今的 服務器大概在3000臺左右,將來將拓展到 10000 萬,這就是運維的挑戰了。

58同城沈劍:好的架構是進化來的,不是設計來的

總結:

最後作一個小的總結,網站在不一樣的階段遇到的問題不同,而解決這些問題使用的技術也不同,流量小的時候,咱們主要目的是提升開發效率,在早期要 引入 ORM,DAO 這些技術。隨着流量變大,使用動靜分離、讀寫分離、主從同步、垂直拆分、CDN、MVC 等方式不斷提高網站的穩定性。面對更大的流量時,經過垂直拆分、服務化、反向代理、開發框架(站點/服務)等等,不斷提高高可用。在面對上億級的更大流量 時,經過中心化、柔性服務、消息總線、自動化(迴歸,測試,運維,監控)來迎接新的挑戰。將來的就是繼續實現 移動化,大數據實時計算,平臺化…

相關文章
相關標籤/搜索