好的架構(gòu)不是設(shè)計出來的蓄拣,而是演進出來的

好的架構(gòu)不是設(shè)計出來的,而是演進出來的

對很多創(chuàng)業(yè)公司而言努隙,很難在初期就預(yù)估到流量十倍球恤、百倍以及千倍以后網(wǎng)站架構(gòu)會是什么樣的一個狀況。同時荸镊,如果系統(tǒng)初期就設(shè)計一個千萬級并發(fā)的流量架構(gòu)咽斧,很難有公司可以支撐這個成本。

因此躬存,這里主要會關(guān)注架構(gòu)的眼花张惹。在每個階段,找到對應(yīng)該階段網(wǎng)站架構(gòu)所面臨的問題岭洲,然后在不斷解決這些問題宛逗,在這個過程中整個架構(gòu)會一直演進。

在58同城建立之初盾剩,站點的流量非常小雷激,可能也就是十萬級別,這也就意味著告私,平均每秒鐘也就是幾次的訪問屎暇,此時網(wǎng)站架構(gòu)的特點是:請求量比較低,數(shù)據(jù)量比較小驻粟,代碼量也比較小根悼。這個時候的站點可以被幾個工程師輕易搞定,因此根本沒什么“架構(gòu)”可言蜀撑。

其實這也是很多創(chuàng)業(yè)公司初期面臨的問題挤巡,最開始58同城的站點架構(gòu)用一個詞概括就是“ALL IN ONE”,如下圖所示:

就像一個單機系統(tǒng)屯掖,所有的東西都部署在一臺機器上,包括站點襟衰、數(shù)據(jù)庫贴铜、文件等等。而工程師每天的核心工作就是CURD瀑晒,前端傳過來一些數(shù)據(jù)绍坝,然后業(yè)務(wù)邏輯層拼裝成一些CURD訪問數(shù)據(jù)庫,數(shù)據(jù)庫返回數(shù)據(jù)苔悦,數(shù)據(jù)拼裝成頁面轩褐,最終返回到瀏覽器。相信很多創(chuàng)業(yè)團隊初期都面臨一個與之類似的情況玖详,每天寫代碼把介,寫SQL勤讽、接口參數(shù)、訪問數(shù)據(jù)等等拗踢。

這里需要說明一個問題脚牍,大家都知道最初58同城使用的是Windows、iis巢墅、SQL-Sever诸狭、C#這條路。現(xiàn)在很多創(chuàng)業(yè)公司可能就不會這么做君纫。

如果可以重來驯遇?那么會選擇LAMP

很多創(chuàng)業(yè)的同學(xué)可能會想,初期什么樣的一個架構(gòu)合適蓄髓? 如果重來叉庐,站在現(xiàn)在這個角度上58會選擇LAMP,為什么双吆?首先是無須編譯眨唬,而且快速發(fā)布功能強大,從前端到后端好乐、數(shù)據(jù)庫訪問匾竿、業(yè)務(wù)邏輯處理等等全部可以搞定,最重要都是成熟的開源產(chǎn)品蔚万,完全免費的岭妖。如果使用LAMP搭建一個論壇,兩天的時間就足夠了反璃。所以昵慌,如果在創(chuàng)業(yè)初期,就盡量不要再使用Windows淮蜈。

在這個階段58同城面臨的主要問題是什么斋攀?其實就是招人,最初工程師寫CURD都容易出錯梧田。當(dāng)時引進了DAO和ORM淳蔼,從而避免直接面對CURD語句,而是面對工程師比較擅長的是面向?qū)ο蟛妹校軌驑O大的提高工作效率鹉梨,降低出錯率。

中等規(guī)模:流量跨過十萬的階段穿稳,數(shù)據(jù)庫成為瓶頸

隨著58同城的高速增長存皂,系統(tǒng)很快跨越了十萬流量階段。主要需求是什么逢艘?網(wǎng)站能夠正常訪問旦袋,當(dāng)然速度更快點就好了骤菠。而此時系統(tǒng)面臨的問題有:在流量峰值期容易宕機,因為大量的請求會壓到數(shù)據(jù)庫上猜憎,所以數(shù)據(jù)庫成為新的瓶頸娩怎,從而,人越多訪問越慢胰柑。而在這個時候截亦,機器數(shù)量也從一臺變成了多臺,所以很自然的行程了分布式架構(gòu)柬讨,如下圖所示:

首先崩瓤,使用了一些非常常見的技術(shù),一方面是動靜分離踩官,動態(tài)的頁面通過Web-Servre訪問却桶,靜態(tài)的像圖片等就單獨放到了一些服務(wù)器上。另外一點就是讀寫分離蔗牡。其實颖系,對58同城或者說絕大部分的站點而言,一般來說都是讀多寫少辩越。對58同城來說嘁扼,絕大部分用戶是訪問信息,只有很少的用戶過來發(fā)貼黔攒。那么如何擴展整個站點架構(gòu)的讀請求呢趁啸?常用的是主從同步,讀寫分離督惰。同時原來只有一個數(shù)據(jù)庫不傅,現(xiàn)在使用多個不同的數(shù)據(jù)庫提供服務(wù),這樣的話赏胚,就擴展了讀寫访娶,很快就解決了中等規(guī)模下數(shù)據(jù)訪問的問題。

在這個階段觉阅,系統(tǒng)的主要矛盾就是“站點耦合+讀寫延時”崖疤,58同城是如何進行解耦,如何緩解延時呢留拾?

對58同城而言戳晌,典型業(yè)務(wù)場景是主頁鲫尊,發(fā)布信息有發(fā)布頁痴柔,信息聚合、標(biāo)題聚合有列表頁疫向,點開一個標(biāo)題有詳細(xì)頁咳蔚,而這些站點都是耦合在一個程序中的豪嚎,或者說耦合在一個站點中的,當(dāng)一個站點出現(xiàn)問題谈火,整個站點就會因為耦合一起出問題侈询。

第二個問題,大家都知道做數(shù)據(jù)庫讀請求和寫請求糯耍,分布在不同的數(shù)據(jù)庫上扔字,這個時候如果再讀取可能讀到的是舊數(shù)據(jù),因為讀寫有一個延時温技。如果有用戶發(fā)帖子革为,馬上去找的話肯定找不到,很可能帶來的后果就是陸續(xù)在發(fā)布兩條信息舵鳞,這就是一個很大的問題震檩。尤其是在請求量越來越大的時候,這個問題就更加突出蜓堕。

在解決這些問題時抛虏,最先想到的是針對原來站點的核心業(yè)務(wù)做切分,然后工程師根據(jù)自己的站點和業(yè)務(wù)場景進行細(xì)分套才。首先迂猴,業(yè)務(wù)拆分是58同城最先嘗試的優(yōu)化——將業(yè)務(wù)垂直拆分成了首頁和發(fā)布頁。另外霜旧,在數(shù)據(jù)庫層面错忱,隨之也進行了拆分,將大數(shù)據(jù)量拆分成一個個小的數(shù)據(jù)量挂据。這樣以清,讀寫延時就馬上得到了緩解。尤其是在代碼拆分成了不同的層面之后崎逃,站點耦合也得到了緩解掷倔,數(shù)據(jù)加載速度也提升了很多。

當(dāng)時个绍,還使用了一些技術(shù)勒葱,前面也提到了對動態(tài)資源和靜態(tài)資源進行拆分。其中巴柿,我們對靜態(tài)資源使用了CDN服務(wù)凛虽,便于數(shù)據(jù)緩存和就近訪問,訪問速度得到很明顯的提升广恢。除此之外凯旋,還使用了MVC模式,擅長前端的去做展示層,擅長協(xié)作邏輯的工程師就做Contorller至非,擅長數(shù)據(jù)的人就負(fù)責(zé)數(shù)據(jù)钠署,效率就會逐步的提高,最后就是負(fù)載均衡技術(shù)荒椭。

大流量:將整個Windows技術(shù)體系轉(zhuǎn)向了Java體系

流量越來越大谐鼎,當(dāng)流量超過一千多萬時,58同城面臨的最大問題就是性能和成本趣惠。此前曾提到58同城最初的技術(shù)選型是Windows狸棍,整個網(wǎng)站的性能變得非常之低。即使進行了業(yè)務(wù)拆分和一些優(yōu)化味悄,依然解決不了這個問題隔缀,所以當(dāng)時做了一個非常艱難的決定,就是轉(zhuǎn)型:將整個Windows技術(shù)體系轉(zhuǎn)向了Java體系傍菇,這涵蓋了操作系統(tǒng)猾瘸、數(shù)據(jù)庫等多個維度。

其實丢习,現(xiàn)在很多大的互聯(lián)網(wǎng)公司在流量從小到大的過程中都經(jīng)歷過轉(zhuǎn)型牵触,包括京東、淘寶等等咐低。對技術(shù)的要求越來越高揽思,任何一個站點都不能掛,對站點的可用性要求也是越來越高见擦。

就在這個時候钉汗,58同城業(yè)務(wù)量也出現(xiàn)一個爆發(fā)期。于是招聘了很多工程師鲤屡,大家一起寫越來越多的站點损痰,但是發(fā)現(xiàn)效率很低,經(jīng)常做一些重復(fù)性的工作酒来,比如參數(shù)解析等等卢未。同時,業(yè)務(wù)之間相互依賴堰汉,無論是分類的子系統(tǒng)還是信息的子系統(tǒng)辽社,二手車業(yè)務(wù)、房產(chǎn)業(yè)務(wù)都要訪問用戶和信息等一些底層數(shù)據(jù)翘鸭,代碼之間頻繁的溝通滴铅,效率也不可能很高。

問題隨之而來就乓,站點數(shù)越來越多汉匙,數(shù)據(jù)量越來越大譬淳,機器數(shù)從最開始的幾臺上升到幾百臺的級別。那么如何提供整個架構(gòu)的可用性呢盹兢?首先,在上層進行了一些改進和優(yōu)化守伸,再做進一步的垂直拆分绎秒,同時引入了Cache,如下圖所示:

在架構(gòu)的改進上尼摹,這里構(gòu)建了一個相對獨立的服務(wù)層见芹,這個服務(wù)層做的每個業(yè)務(wù)線都會寫對應(yīng)的代碼。如果用戶發(fā)出請求蠢涝,就由這個服務(wù)層統(tǒng)一來管理玄呛,所有的上游業(yè)務(wù)線就像調(diào)用本地函數(shù)一樣,通過IDC的框架來調(diào)用這個服務(wù)和二。整個用戶登錄先訪問Cache徘铝,如果Cache變動了就直接返回,如果Cache不變動惯吕,就會訪問數(shù)據(jù)庫惕它,這樣把數(shù)據(jù)庫的數(shù)據(jù)拿到本地再放回Cache,再打回上一輪废登。如此一來淹魄,業(yè)務(wù)邏輯全部封裝在這個服務(wù)的上游管理,該業(yè)務(wù)邏輯只有服務(wù)層能夠編寫代碼堡距,然后由這個服務(wù)層集中管理甲锡、集中優(yōu)化,這樣就提高了效率羽戒。

除此之外缤沦,為了保證站點的高可用,主要使用了反向代理技術(shù)易稠。因為對用戶而言疚俱,他主要為了使用58同城的服務(wù),不會關(guān)注訪問是58同城或者有十臺首頁的服務(wù)器缩多。58同城通過反向代理技術(shù)呆奕,通過DNS群,通過LVS技術(shù)衬吆,來保證接入層的高可用性梁钾,同時還保證了服務(wù)層、站點層逊抡、數(shù)據(jù)層的高可用姆泻。另外零酪,為了保證高可用還使用了冗余的方法,無論是站點服務(wù)和數(shù)據(jù)服務(wù)都可以使用這種方式進行解決拇勃,一個站點不可用四苇,就換一個站點,一個數(shù)據(jù)庫不夠用方咆,就多加幾個月腋。當(dāng)然,數(shù)據(jù)冗余也會帶來一些副作用瓣赂,如果數(shù)據(jù)量更新的話榆骚,那就需要將所有的“冗余”都要進行更新。

58同城也做了一個圖片存儲系統(tǒng)煌集,開始都是存儲在操作系統(tǒng)之上妓肢,隨著新增站點、新增服務(wù)苫纤,壓力就變得越來越大碉钠。于是,58同城就自建了站點框架和服務(wù)框架卷拘,現(xiàn)在這兩個框架也已經(jīng)開源(如何降低站點開發(fā)成本放钦?https://github.com/58code/Argo?如何降低服務(wù)開發(fā)成本?https://github.com/58code/Gaea)只需要修改一些基本的配置就可以使用了恭金。

當(dāng)架構(gòu)變成“蜘蛛網(wǎng)”操禀,人肉已很難搞定!

隨著用戶量横腿、數(shù)據(jù)量并發(fā)量進一步的增長颓屑,58同城也拓展了很多的新業(yè)務(wù),那么對產(chǎn)品迭代速度要求就非常高耿焊,整體的架構(gòu)對自動化的要求越來越高揪惦。

為了支撐業(yè)務(wù)的發(fā)展,技術(shù)團隊對架構(gòu)做了進一步的解耦罗侯,另外就是引入了配置中心器腋,如果要訪問任何一個服務(wù),不會直接在本地的配置中留下一個服務(wù)钩杰,配置中心告訴這個服務(wù)的特點纫塌,如果擴展的話,配置中心自動下達消息讲弄,如果有機器要下線的話措左,配置中心會反向通過發(fā)郵件的方式進行通知。

而柔性服務(wù)是指當(dāng)流量增加的時候避除,自動的新增服務(wù)怎披⌒剜遥可以看到進一步解耦之后,有垂直業(yè)務(wù)凉逛、無線業(yè)務(wù)性宏、集成業(yè)務(wù)等等,這些子系統(tǒng)之間都是通過配置中心相應(yīng)之間發(fā)生關(guān)系的状飞。

另一點就是關(guān)于數(shù)據(jù)庫毫胜,當(dāng)某一點成為一個業(yè)務(wù)線重點的時候,就會集中解決這個點的問題昔瞧。最初期的時候每個業(yè)務(wù)線都要訪問數(shù)據(jù)庫,訪問緩存菩佑,訪問用戶數(shù)據(jù)自晰,于是把代碼集中的放到了服務(wù)層。現(xiàn)在數(shù)據(jù)量越來越大稍坯,大家都要做數(shù)據(jù)切分酬荞,每個業(yè)務(wù)線都做切分,這個時候58同城的每個頁面都面對這樣的痛點瞧哟,于是把這個痛點拿到集中的層面來解決混巧。

最后一點就是效率矛盾,此時有很多問題勤揩,靠“人肉”已經(jīng)很難進行搞定了咧党。這就需要自動化,包括回歸陨亡、測試傍衡、運維、監(jiān)控等等都要回歸到自動化负蠕。

這里需要補充一點蛙埂,就是在產(chǎn)品層面引入了智能化,比如說智能推薦遮糖,主動推薦一些相關(guān)的話題绣的;智能廣告,通過一些智能的策略欲账,讓用戶對廣告的點擊更多屡江,增加對58同城的收錄;智能搜索赛不,在搜索的過程中加入一些搜索的策略盼理,可以提高搜索的權(quán)重,也可以增加58同城的PV俄删。當(dāng)然宏怔,所有的自動化的產(chǎn)品背后都是由技術(shù)在驅(qū)動奏路。

未來的挑戰(zhàn)

現(xiàn)在,58同城的流量已經(jīng)突破了10億量級臊诊,那么架構(gòu)上未來面臨哪些挑戰(zhàn)呢鸽粉?一方面是無線化、移動化抓艳。另一方面就是需求的變化触机,必須加快迭代一些東西。如果擁有10億的流量玷或,卻跑在一億的架構(gòu)上肯定是不行的儡首。未來,還會使用更多的并行計算偏友、實時計算蔬胯,如果能做到實時推薦,效果肯定非常好位他,這也是挑戰(zhàn)之一氛濒。最后一點,58同城現(xiàn)在的服務(wù)器大概在3000臺左右鹅髓,未來將拓展到10000臺舞竿,這就是運維的挑戰(zhàn)了。

總結(jié)

最后做一個小的總結(jié)窿冯,網(wǎng)站在不同的階段遇到的問題不一樣骗奖,而解決這些問題使用的技術(shù)也不一樣,流量小的時候醒串,主要目的是提高開發(fā)效率重归,在早期要引入ORM,DAO這些技術(shù)厦凤。隨著流量變大鼻吮,使用動靜分離、讀寫分離较鼓、主從同步椎木、垂直拆分、CDN博烂、MVC等方式不斷地提升網(wǎng)站穩(wěn)定性香椎。面對更大的流量時,通過垂直拆分禽篱、服務(wù)化姨蟋、反向代理爵川、開發(fā)框架(站點/服務(wù))等等曹抬,不斷提升高可用。在面對上億級的更大流量時万矾,通過中心化、柔性服務(wù)慎框、消息總線良狈、自動化(回歸,測試笨枯,運維薪丁,監(jiān)控)來迎接新的挑戰(zhàn)。未來的就是繼續(xù)實現(xiàn).

作者:58沈劍

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末馅精,一起剝皮案震驚了整個濱河市严嗜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌洲敢,老刑警劉巖漫玄,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沦疾,居然都是意外死亡称近,警方通過查閱死者的電腦和手機第队,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門哮塞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人凳谦,你說我怎么就攤上這事忆畅。” “怎么了尸执?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵家凯,是天一觀的道長。 經(jīng)常有香客問我如失,道長绊诲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任褪贵,我火速辦了婚禮掂之,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘脆丁。我一直安慰自己世舰,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布槽卫。 她就那樣靜靜地躺著跟压,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歼培。 梳的紋絲不亂的頭發(fā)上震蒋,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天茸塞,我揣著相機與錄音,去河邊找鬼喷好。 笑死翔横,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的梗搅。 我是一名探鬼主播禾唁,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼无切!你這毒婦竟也來了荡短?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤哆键,失蹤者是張志新(化名)和其女友劉穎掘托,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體籍嘹,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡闪盔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了辱士。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泪掀。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖颂碘,靈堂內(nèi)的尸體忽然破棺而出异赫,到底是詐尸還是另有隱情,我是刑警寧澤头岔,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布塔拳,位于F島的核電站,受9級特大地震影響峡竣,放射性物質(zhì)發(fā)生泄漏靠抑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一适掰、第九天 我趴在偏房一處隱蔽的房頂上張望颂碧。 院中可真熱鬧,春花似錦攻谁、人聲如沸稚伍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽个曙。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間垦搬,已是汗流浹背呼寸。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留猴贰,地道東北人对雪。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像米绕,于是被迫代替她去往敵國和親瑟捣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容