Web項(xiàng)目的結(jié)構(gòu)

一個(gè)Web項(xiàng)目, 可大可小, 大到整個(gè)阿里巴巴, 小到你自己的博客, 留言板. 雖然所采用的技術(shù)不一樣, 規(guī)模不一樣, 但是都由一些執(zhí)行相同作用的組件所構(gòu)成的, 當(dāng)然根據(jù)規(guī)模的不同, 要實(shí)現(xiàn)的功能的不同, 有一些組件并不一定是必須, 但是當(dāng)一個(gè)項(xiàng)目從小到大的演變過程中, 需要加入的組件都是大致功能類似的. 下面我們就從最簡單的Web項(xiàng)目開始, 到隨著功能, 規(guī)模的遞增, 看看有那些組件需要加入, 和各自的作用.

1. 種子規(guī)模

這個(gè)規(guī)模的項(xiàng)目最好的實(shí)例就是個(gè)人博客, 留言板, 公司介紹網(wǎng)站等, 基本結(jié)構(gòu)如下

種子規(guī)模項(xiàng)目結(jié)構(gòu)


這是最簡單的模式, 基本上可以概括為 ?請求-響應(yīng) 模式. 主要的組件是由Web框架 和 數(shù)據(jù)庫兩個(gè)部分組成, Web框架負(fù)責(zé)為開發(fā)者提供基礎(chǔ)的應(yīng)用程序結(jié)構(gòu)和功能: 1. 接收HTTP請求 2.渲染返回的HTML頁面, 數(shù)據(jù)庫則負(fù)責(zé)持久化數(shù)據(jù): 比如留言的內(nèi)容.

隨著使用人數(shù)的上升, 性能很快入不敷出, 你開始覺得訪問的時(shí)候速度不如原來快了. 但是你在用top命令查看系統(tǒng)開銷的時(shí)候會(huì)發(fā)現(xiàn), 其實(shí)系統(tǒng)的CPU占用并不是很高. 原來這個(gè)時(shí)候大部分的時(shí)候CPU都在等帶數(shù)據(jù)庫查詢的結(jié)果, 而數(shù)據(jù)庫查詢結(jié)果很多時(shí)候是重復(fù)的, 比如當(dāng)沒有人留言的時(shí)候, 返回的最新留言列表. 為了避免無謂的IO開銷, 我們需要用一個(gè)比數(shù)據(jù)庫快N倍的存儲(chǔ)設(shè)備來緩存查詢的結(jié)果, 這樣當(dāng)我們發(fā)現(xiàn)查詢結(jié)果不會(huì)有變化的時(shí)候, 就能通過更快的存儲(chǔ)設(shè)備拿到結(jié)果, 比如內(nèi)存就是用戶級(jí)應(yīng)用程序能訪問的最快, 而且現(xiàn)在看來容量也夠大(將來會(huì)越來越大)的存儲(chǔ)設(shè)備了. 這個(gè)時(shí)候我們需要引入一個(gè)新的組件: 內(nèi)存緩存

2. 發(fā)芽規(guī)模(開始擴(kuò)展了)

引入緩存后, 項(xiàng)目的基本結(jié)構(gòu)如下圖所示:


帶緩存的項(xiàng)目結(jié)構(gòu)

目前最常用的內(nèi)存緩存基本上就MemoryCache和Redis兩個(gè)了, MemoryCache就是個(gè)單存的內(nèi)存緩存, 而Redis不光快, 還是個(gè)啥都能干的萬金油, 你可以將其視作為一個(gè)在線內(nèi)存數(shù)據(jù)結(jié)構(gòu)服務(wù), 除了KV之外還提供了SET, List, Hash等多種數(shù)據(jù)結(jié)構(gòu), 功能太強(qiáng)我們后面還會(huì)提到詳細(xì)說.

緩存大體上有兩種使用的方式, 一種是輸出緩存, 另一種是數(shù)據(jù)緩存.

輸出緩存是作用在Web框架輸出端, 基本的作用過程是這樣子的.

輸出緩存執(zhí)行邏輯

當(dāng)讀取的頻率大于寫入或者更新的時(shí)候, 輸出緩存能夠很大程度上的提升性能, 因?yàn)榇蟛糠衷拘枰ㄟ^數(shù)據(jù)庫去獲取的數(shù)據(jù)直接通過內(nèi)存獲得了, 而內(nèi)存的速度是數(shù)據(jù)庫的N倍, 所以系統(tǒng)的容量能夠成倍的增長.

但是, 如果輸出的內(nèi)容需要在數(shù)據(jù)的基礎(chǔ)上做一些處理, 比如返回了留言列表, 但是要根據(jù)和當(dāng)前日期的比對(duì)顯示留言的時(shí)間, 最近的幾條顯示諸如: 剛剛, 1分鐘前, 半小時(shí)前... 等. 隨著時(shí)間的變動(dòng), 返回的留言沒變, 但是留言時(shí)間的顯示需要變化, 那么這個(gè)時(shí)候輸出緩存就無能為力了, 我們需要數(shù)據(jù)緩存來滿足需求.

數(shù)據(jù)緩存的執(zhí)行邏輯如下圖所示:

數(shù)據(jù)緩存執(zhí)行邏輯

但是這兩種緩存模式都是在項(xiàng)目中根據(jù)需要來使用, 大多數(shù)時(shí)候一個(gè)項(xiàng)目中兩種模式都會(huì)存在.在實(shí)際的項(xiàng)目中緩存并非只有自建一種選擇, 還有客戶端緩存和CDN之類的緩存形式, 我們在緩存的部分專門展開來詳細(xì)介紹.

隨著規(guī)模的增長, 功能的增加, 有的時(shí)候我們需要在項(xiàng)目中增加一些很耗時(shí)的操作, 比如上傳了視頻后需要壓縮視頻等操作, 會(huì)產(chǎn)生大量的IO等待, 又比如一些匯總查詢, 都是很耗時(shí)的操作, 這個(gè)時(shí)候我們就需要將這些操作放到別的進(jìn)程去執(zhí)行, 那么就又需要加入兩個(gè)新的組件: 消息總線和任務(wù)服務(wù).

3.小苗規(guī)模

這個(gè)階段呢, 有一些需求會(huì)需要訪問慢IO, 或者產(chǎn)生高CPU運(yùn)算的任務(wù), 會(huì)嚴(yán)重影響系統(tǒng)的吞吐量. 這個(gè)時(shí)候我們需要充分的運(yùn)用多核CPU的優(yōu)勢, 將耗時(shí)的工作交給別的CPU去搞定, 所以需要一個(gè)進(jìn)程管理器來管理一組進(jìn)程來專門接收-執(zhí)行這些任務(wù), 而為了通知這些進(jìn)程來獲取要執(zhí)行任務(wù)的數(shù)據(jù), 需要消息總線來負(fù)責(zé)在Web應(yīng)用和進(jìn)程管理器之間來傳遞消息.?

加上這兩個(gè)組件后, 項(xiàng)目的結(jié)構(gòu)變成了這樣子:

在這個(gè)階段, 我們已經(jīng)可以精細(xì)的將不同開銷的任務(wù)解藕開, 將高開銷, 高耗時(shí)的邏輯從Web的主進(jìn)程中剝離出來, 從而滿足進(jìn)一步擴(kuò)大系統(tǒng)吞吐量的目的.

而消息服務(wù)的引入進(jìn)一步擴(kuò)展了系統(tǒng)的彈性, 我們可以將不同的功能分解成獨(dú)立的服務(wù), 各自通過消息服務(wù)整合起來, 從而實(shí)現(xiàn)了整個(gè)系統(tǒng)的微服務(wù)化.

在這個(gè)結(jié)構(gòu)下, 一個(gè)開銷很大的請求的執(zhí)行過程如下:

由任務(wù)服務(wù)處理的請求執(zhí)行過程

在這個(gè)階段, 各個(gè)模塊已經(jīng)實(shí)現(xiàn)了基本上的解藕, 無論是功能或者容量上的擴(kuò)展都比較方便了, 所以接下來的目標(biāo)就是針對(duì)一個(gè)特殊的需求添加必要的組件了

4. 小樹規(guī)模(生長枝條)

演變到這個(gè)階段, 系統(tǒng)的大體模型已經(jīng)固定下來了, 生下來的是根據(jù)不同的需要添加一些特殊的組件了.結(jié)構(gòu)如下:


4.1 全文檢索

在傳統(tǒng)的關(guān)系型數(shù)據(jù)庫中, 類似 Like '% 張三 %' 這類的查詢都是會(huì)丟失索引, 所以類似這樣的查詢只有通過全文檢索引擎來搜索才能有足夠的效率, 在互聯(lián)網(wǎng)領(lǐng)域用得最多的MySQL在全文檢索方面的功能太過于孱弱, 所以現(xiàn)在而今眼目下業(yè)內(nèi)大多用Solr, Elasticsearch等全文檢索引擎來提供全文檢索服務(wù). 如果你是PostgreSQL黨的話就會(huì)省心很多, 數(shù)據(jù)庫自帶的Gist, Gin, Brin這些類型的索引都能提供很好的全文檢索能力.

4.2 日志系統(tǒng)(收集+存儲(chǔ)+檢索)

當(dāng)整個(gè)系統(tǒng)都微服務(wù)化后, 服務(wù)進(jìn)程數(shù)量很多, 且會(huì)分布在不同的主機(jī)上, 這個(gè)時(shí)候再將日志寫到本地磁盤上, 采集整理日志會(huì)非常的痛苦, 所以需要統(tǒng)一的日志系統(tǒng)來處理系統(tǒng)日志.

一般的日志系統(tǒng)都是由 前端采集器 - 采集對(duì)列 - 寫入器 三個(gè)部分構(gòu)成, 數(shù)據(jù)存儲(chǔ)基本上都由全文檢索引擎來搞定了, 這樣方便了后續(xù)對(duì)日志的處理.

4.3 LBS索引

在傳統(tǒng)的關(guān)系型數(shù)據(jù)庫中沒有Gist索引, 所以沒有辦法對(duì)經(jīng)緯度等數(shù)據(jù)進(jìn)行索引, 所以需要單獨(dú)的LBS索引服務(wù). 當(dāng)然對(duì)于PostgreSQL來說并沒有這個(gè)必要.

4.4 OLAP數(shù)據(jù)倉庫(數(shù)據(jù)分析)

我們常用的MySQL, PostgreSQL都是OLTP型的關(guān)系型數(shù)據(jù)庫, 也就是針對(duì)聯(lián)機(jī)事務(wù)處理優(yōu)化模式工作的數(shù)據(jù)庫, 俗話說就是針對(duì) 增刪改查等操作專門優(yōu)化, 跑起來傻快傻快的, 但是對(duì)于要做匯總查詢之類的就速度上不行了. 如果要對(duì)數(shù)據(jù)進(jìn)行專門的挖掘鉆取的話, 需要把數(shù)據(jù)存入專門對(duì)數(shù)據(jù)分析優(yōu)化的OLAP類型的數(shù)據(jù)倉庫中. 術(shù)業(yè)有專攻, 這個(gè)領(lǐng)域不是強(qiáng)項(xiàng)所以簡略帶過, 后面有機(jī)會(huì)再詳細(xì)說

以上所有的服務(wù)我們在后面都有相應(yīng)的主題來詳細(xì)描述, 這里就簡略帶過了.

5. 大樹規(guī)模(群集化, 超大規(guī)模)

在這個(gè)階段, 結(jié)構(gòu)得到了充分的展開, 每一個(gè)組件充分的解藕, 就能夠根據(jù)具體的系統(tǒng)負(fù)載來針對(duì)特定的瓶頸來優(yōu)化, 擴(kuò)容, 升級(jí). 這個(gè)時(shí)候并沒有一個(gè)固定的模式了, 不同的業(yè)務(wù)需求, 不同的數(shù)據(jù)類型都會(huì)造成在這個(gè)階段的需求是不一樣的, 結(jié)構(gòu)也是不一樣的, 所以我們會(huì)單獨(dú)拿一個(gè)主題來詳細(xì)說明.

下一節(jié)主題: Web框架如何快速入門

to be continue...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子庇配,更是在濱河造成了極大的恐慌,老刑警劉巖桩警,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異侣姆,居然都是意外死亡生真,警方通過查閱死者的電腦和手機(jī)沉噩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門捺宗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人川蒙,你說我怎么就攤上這事蚜厉。” “怎么了畜眨?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵昼牛,是天一觀的道長。 經(jīng)常有香客問我康聂,道長贰健,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任恬汁,我火速辦了婚禮伶椿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己脊另,他們只是感情好导狡,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著偎痛,像睡著了一般旱捧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上踩麦,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天枚赡,我揣著相機(jī)與錄音,去河邊找鬼谓谦。 笑死标锄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的茁计。 我是一名探鬼主播料皇,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼星压!你這毒婦竟也來了践剂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤娜膘,失蹤者是張志新(化名)和其女友劉穎逊脯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竣贪,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡军洼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了演怎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匕争。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖爷耀,靈堂內(nèi)的尸體忽然破棺而出甘桑,到底是詐尸還是另有隱情,我是刑警寧澤歹叮,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布跑杭,位于F島的核電站,受9級(jí)特大地震影響咆耿,放射性物質(zhì)發(fā)生泄漏德谅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一萨螺、第九天 我趴在偏房一處隱蔽的房頂上張望窄做。 院中可真熱鬧宅荤,春花似錦、人聲如沸浸策。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庸汗。三九已至惫确,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蚯舱,已是汗流浹背改化。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枉昏,地道東北人陈肛。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像兄裂,于是被迫代替她去往敵國和親句旱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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