系統(tǒng)中的非功能性需求
今天我們的主是當(dāng)當(dāng)高可用架構(gòu)設(shè)計(jì)之道,高可用并不是功能性的需求,而是傳統(tǒng)的IT當(dāng)中非功能性需求的一部分。大家可以看到我這里羅列了很多非功能性需求,但是這當(dāng)中并沒有「高可用」這三個(gè)字。
舉一個(gè)例子,比如說你買了一臺(tái)蘋果手機(jī),無論是作為手機(jī)還是電腦,還是MP3,還是專門用來看視頻的,都是功能;那么非功能性呢,比如說大家很崇 拜喬布斯,產(chǎn)品設(shè)計(jì)極致體驗(yàn),蘋果手機(jī)只有1個(gè)鍵,簡(jiǎn)單好用,這就是一個(gè)非功能性需求。另外還有很多朋友買土豪金的手機(jī),就是為了區(qū)分開,因?yàn)轭伾灰?樣。這個(gè)顏色也是非功能性需求。
我們簡(jiǎn)單介紹幾個(gè)非功能性需求。
擴(kuò)展性,有一些類似的可以抽象成統(tǒng)一模型的東西,如果說做好的話就可以支持?jǐn)U展。用一個(gè)以前的例子,我以前是 做電信行業(yè)的,比如說有一個(gè)需求要在全球通上開一個(gè)5塊錢的套餐,接著又要在動(dòng)感地帶開一個(gè)10塊錢的套餐,那么我們就可以做成一個(gè)模型,做成一個(gè)套餐的 產(chǎn)品,品牌是一個(gè)屬性,價(jià)格也是一個(gè)屬性。這樣的話,神州行再來一個(gè)50塊錢的套餐,我們就不需要改什么應(yīng)用,增加一些配置,定義一些產(chǎn)品屬性就可以了, 這就是擴(kuò)展性。
高效率是說你對(duì)現(xiàn)有的資源使用是不是足夠高效。比如說有的人寫的代碼比較爛,一啟動(dòng)就百分之幾十的CPU使用率,這就不太合理。
可測(cè)試,很多開發(fā)的同學(xué)不當(dāng)回事,覺得開發(fā)好功能邏輯就夠了。但是你做出來的東西是要保證質(zhì)量的。開個(gè)玩笑, 如果說測(cè)試的妹子很漂亮,你愿意手把手的教她如何來測(cè)試功能,但要是妹子走了,來了一個(gè)糙爺們還需要你還手把手的教,你就不愿意了。因此必須要有一個(gè)測(cè)試 的完整方法、功能說明、測(cè)試用例。
這些非功能性的需求,是整個(gè)系統(tǒng)是不是正常穩(wěn)定、可靠運(yùn)轉(zhuǎn),以及被一個(gè)團(tuán)隊(duì)長(zhǎng)期沿用下去的一個(gè)前提。
而可用性,涉及到很多方面。比如說伸縮性,是否能夠在業(yè)務(wù)量增長(zhǎng)的前提之下,通過水平擴(kuò)展可以很容易支撐更多的業(yè)務(wù)。比如說安全性、可靠性,數(shù)據(jù)會(huì)不會(huì)丟失?所以這里面很多的點(diǎn),最終都是決定了可用性。
那么可用性是什么呢?可用性就是這套系統(tǒng)最終是給用戶用的,是有這些功能的,但是其他方面如果不能保障好,不能N個(gè)用戶一直用,那你這個(gè)系統(tǒng)就無 法體現(xiàn)它的價(jià)值。這是非常重要的,很多剛剛工作幾的,或者是一直在做產(chǎn)品研發(fā)的同學(xué),對(duì)這方面沒有切身的體會(huì),沒有在大晚上被人打電話說出了什么問你 趕緊來處理一下,沒有這樣切身的痛苦的體會(huì)。
「高可用」到底是什么
接下來我們說一下什么是高可用。CAP理論是指在分布式數(shù)據(jù)的場(chǎng)景來形容三者不可兼得,就是一致性、可用性和分區(qū)容忍性。在整個(gè)系統(tǒng)層面也可以這么理解,因?yàn)槎鄶?shù)系統(tǒng)的核心就是數(shù)據(jù),數(shù)據(jù)本身受限于這三個(gè)特性只能滿足兩個(gè),不能三個(gè)一起滿足,整個(gè)系統(tǒng)也是如此。
在互聯(lián)網(wǎng)場(chǎng)景里,因?yàn)閿?shù)據(jù)量大分區(qū)容忍性是必須要支持的。一致性可以稍微容忍一些,但是可用性是一定要保證的。所以最后多數(shù)的互聯(lián)網(wǎng)公司多數(shù)的業(yè)務(wù)系統(tǒng)就是犧牲一致性,保證可用性和分區(qū)容忍性。
我們繼續(xù)往下看,什么可以影響可用性。
其次是人禍,攜程公司去也發(fā)生了「慘案」,系統(tǒng)宕機(jī)一下午,一直到晚上才恢復(fù);還有阿里云,去上了一個(gè)云盾的功能,用戶在執(zhí)行可執(zhí)行文件的時(shí) 候,就把這個(gè)可執(zhí)行文件給刪了,回頭用戶再找這個(gè)可執(zhí)行文件的時(shí)候就找不到了。還有是BUG,在某一些特定場(chǎng)景下系統(tǒng)出問,這是很正常的。
設(shè)計(jì)缺陷是要重點(diǎn)說的,它比BUG更宏觀一些,是結(jié)構(gòu)上的問,不是說你增加幾個(gè)判斷,改一下代碼就可以解決的。基本上是屬于一旦發(fā)現(xiàn)了,要么就是大改,要么就是重構(gòu),調(diào)整原來的設(shè)計(jì),很難馬上去解決。
至于說性能瓶頸和資源不足,大家知道就是這么多的服務(wù)器,如果代碼性能寫得好,可能能扛住更多請(qǐng)求,如果寫得差,可能稍微增長(zhǎng)一些就不行了。
性能瓶頸就是短板,比如說負(fù)責(zé)某個(gè)模塊是一個(gè)沒有什么經(jīng)驗(yàn)的小同學(xué),代碼質(zhì)量不太高,他就可能成為了整個(gè)系統(tǒng)的短板,這個(gè)模塊出了問,其他的代碼寫得再好,整個(gè)系統(tǒng)還是不能用。
最后還有一些未知的情況。大家做技術(shù)做的時(shí)間長(zhǎng)會(huì)遇到很多無法解釋的「未解之謎」,我們一般稱之為「靈異事件」,這個(gè)是指經(jīng)常發(fā)生的,你不知道問在哪里,但是過段時(shí)間就來一次,就好象冥冥之中有人玩你一樣,但是總歸是可以找到原因解決的。
至于說黑天鵝的事件,則是以前從來沒有出現(xiàn)過的情況,突然出現(xiàn)了,讓你不知道應(yīng)該怎么辦,而且可能是一兩才出現(xiàn)一次,你會(huì)要慮值不值得找它如何出現(xiàn)的。
還有一些以后就再也不出現(xiàn)了,誰也不知道是怎么回事,你就不知道怎么辦了。最后一個(gè)是未知的,我們不知道會(huì)出現(xiàn)什么樣的事情,出現(xiàn)的情況我們也不知道如何應(yīng)對(duì)??茖W(xué)告訴我們,已知的我們可以去努力解決,但是未知的,我們無法判斷。
關(guān)于系統(tǒng)故障,有一個(gè)海因法則,意思是說出現(xiàn)一起嚴(yán)重的事故,都是由很多的隱患,很多的小問,或者說一些問沒有暴露出來,最終引發(fā)特別大的事 故。負(fù)責(zé)運(yùn)維的同學(xué)都知道,公司對(duì)系統(tǒng)的可用性是有指標(biāo)的,是99.9%還是99.99%,還是99.999%,如果說公司沒有這個(gè)東西壓著你作為 KPI,那就太幸運(yùn)了,出了問不至于讓你拿不到獎(jiǎng)金。如果說你的公司有,我希望研發(fā)和架構(gòu)的同學(xué)都要清楚,而不是只有運(yùn)維的同學(xué)知道,否則就是公司管理 不到位,舉個(gè)例子如果可用性標(biāo)準(zhǔn)是99.99%,一系統(tǒng)可以掛的時(shí)間是53分鐘,99.999%則是5分鐘,大家想想就知道,攜程掛了一下午,整個(gè)可用 指標(biāo)就完不成了,KPI就完成不了。
高可用同時(shí)是一個(gè)概率的問。一個(gè)復(fù)雜的系統(tǒng),比如說很多模塊或者子系統(tǒng)組成的系統(tǒng),是可以通過一些方式大概 去估算的。前些云計(jì)算很火,很多人都說我們有一個(gè)云要自動(dòng)運(yùn)行,幾萬臺(tái)服務(wù)器必須要有自動(dòng)恢復(fù)的系統(tǒng),最好是分鐘級(jí)恢復(fù),秒級(jí)恢復(fù)。這些都是一個(gè)概率, 怎么去算呢?比如說我有兩個(gè)手機(jī),最近一個(gè)月內(nèi)有3次差一點(diǎn)丟1臺(tái)手機(jī),這是未遂事件,那么基本上我丟失的概率就確定了,比如說是1/30。我有兩個(gè)手機(jī) 的話有什么好處,沒有手機(jī)用的概率就是1/900。但是丟手機(jī)的概率增加了,我就要做好心理準(zhǔn)備,沒準(zhǔn)哪天就會(huì)失去一個(gè)。
多數(shù)系統(tǒng)是幾臺(tái)或者是幾十臺(tái)服務(wù)器組成一個(gè)小的集群,還有很多跟它平行和上下依賴的系統(tǒng)。這種系統(tǒng)都可以用這種方式去算,大概是什么樣的概率。
這個(gè)還涉及到容量評(píng)估,要慮系統(tǒng)負(fù)載是多少?比如說像我們以前做企業(yè)級(jí)系統(tǒng)用小型機(jī),小型機(jī)的可靠性非常高,平時(shí)就是50%左右的負(fù)載,這個(gè)時(shí) 候三四臺(tái)機(jī)器加在一起就夠用了,因?yàn)閽煲慌_(tái)基本上系統(tǒng)不會(huì)有太大影響。但是如果用不太可靠的PC服務(wù)器或者其他解決方式,因?yàn)閾?dān)心可能出現(xiàn)的狀況,所以現(xiàn) 在很多互聯(lián)網(wǎng)公司采取的是常運(yùn)行10%的CPU或者是20%的CPU狀態(tài)。
我們可以慮一個(gè)系統(tǒng),比如說一臺(tái)機(jī)器掛了,影響系統(tǒng)部分出現(xiàn)問的概率有多高,多個(gè)系統(tǒng)總有一天會(huì)出問,如果說系統(tǒng)足夠大,大家可以想像,無 論是Facebook、谷歌,還是BAT基本上每天都會(huì)有各種各樣的小問。所以越復(fù)雜的系統(tǒng)越是難以評(píng)估,我們要保證出現(xiàn)問的時(shí)候可控。高可用并不是 萬無一失,我們是用更多出問的概率去降低整個(gè)系統(tǒng)出問的概率。
還有一個(gè)說法叫墨菲定律?;旧夏阆氲降淖顗牡氖虑樗倳?huì)發(fā)生的。上學(xué)的時(shí)候,數(shù)學(xué)老師會(huì)說,小概率事件基本上不會(huì)發(fā)生。但是在IT,在一個(gè)復(fù)雜 環(huán)境當(dāng)中,在上千臺(tái)上萬臺(tái)服務(wù)器的集群中,幾百人幾千人做的系統(tǒng),一定會(huì)有一天出問的。所以人算不如天算,你算出來概率很低,你保證我出問的概率哪怕 是幾十萬分之一,你覺得這輩子就趕不上了?不見得的。
那么怎么辦?就是時(shí)刻準(zhǔn)備著。這是我做了這么多開發(fā)最大的體會(huì)。我們做的是一個(gè)7×24小時(shí)對(duì)外服務(wù)的系統(tǒng),不能停。不能停的概念不是說像有的 公司那樣,白天有人用,晚上沒人用,晚上出事了,我們來得及修補(bǔ)修補(bǔ)。但是像電商是7×24小時(shí)的,半夜三四點(diǎn)都有下單的。人家在熬夜開心下單的時(shí)候,你 出了問,阻止人家的下單,要不然就是打電話投訴,要不然是找地方吐槽。
系統(tǒng)故障不僅是技術(shù)上的問,最嚴(yán)重的是影響客戶體驗(yàn),前一段時(shí)間我們的評(píng)論系統(tǒng)出了點(diǎn)小問:一個(gè)客戶買了 一個(gè)面條機(jī),反饋說并不是因?yàn)楫a(chǎn)品本身做不好面條要退貨,因?yàn)槠渌?,這個(gè)因?yàn)楫a(chǎn)品已經(jīng)用過了所以按照規(guī)定是不能夠退貨的。結(jié)果用戶想評(píng)論的時(shí)候評(píng)論不 了,用戶就覺得說當(dāng)點(diǎn)擊評(píng)論按鈕時(shí),系統(tǒng)告知接口錯(cuò)誤,覺得這是在針對(duì)他,其實(shí)這只是系統(tǒng)故障,但是用戶并不會(huì)這么想。
當(dāng)你做了各種各樣的準(zhǔn)備,覺得萬無一失了,難免有一天可能還是會(huì)翻船了。但是遇到這樣的事情也是好事,經(jīng)驗(yàn)都是在這個(gè)時(shí)候積累起來的。那么什么是 高可用?基本上就是三句話,降低故障出現(xiàn)的概率;縮小故障影響的范圍;出現(xiàn)故障快速恢復(fù)。不能因?yàn)槭莻€(gè)小問就覺得無所謂,反正我一堆的服務(wù)器,掛一個(gè)就 掛一個(gè)吧,這種情況不好說會(huì)不會(huì)另外一個(gè)也掛了。因此有問要盡快處理,最終的目的就是讓用戶可以正常的使用。
如何設(shè)計(jì)高可用架構(gòu)
高可用架構(gòu)設(shè)計(jì)常用的「姿勢(shì)」。大家看到這是一架飛機(jī)。我們有一個(gè)比喻說做運(yùn)維這種系統(tǒng),就是開著飛機(jī)修飛機(jī)。首先系統(tǒng)一直運(yùn)行,其次運(yùn)營(yíng)、產(chǎn)品 各種業(yè)務(wù)部門會(huì)不停提各種各樣需求,然后領(lǐng)導(dǎo)也許不懂技術(shù),不懂什么叫分支、什么叫循環(huán)、什么叫面向?qū)ο?;但是懂兩個(gè)詞,一個(gè)是敏捷,一個(gè)是迭代。
所以做這件事情的時(shí)候難度是比較高的。我們不能讓這架飛機(jī)停下來歇幾天,把翅膀換了再飛上去;而是常在天上飛的,飛上去的時(shí)候也許就是個(gè)阿帕奇 直升機(jī),特別是創(chuàng)業(yè)公司。回頭要拓展一個(gè)業(yè)務(wù),增加一些功能,做著做著原來的業(yè)務(wù)不行了,新的業(yè)務(wù)變成了主營(yíng)業(yè)務(wù),結(jié)果變成了F15,從直升機(jī)變成了戰(zhàn)斗 機(jī),然后變成F16,變成F22。一旦技術(shù)團(tuán)隊(duì)沒有做好,一頭栽下去,技術(shù)團(tuán)隊(duì)的名聲就砸了。要么是沒做出來,要么是做出來之后一上線掛了,市場(chǎng)費(fèi)用都白 花了,這個(gè)責(zé)任要技術(shù)來承擔(dān)。
我在四個(gè)領(lǐng)域里面分別提煉了幾條高可用相關(guān)的架構(gòu)方式。
業(yè)務(wù)架構(gòu)就是指產(chǎn)品是什么功能,有什么要求。
首先是領(lǐng)域切分,不要把雞蛋放在一個(gè)籃子里,比如說一些傳統(tǒng)網(wǎng)站,有非常多的二級(jí)域名。某一個(gè)二級(jí)域名掛了,都是不同的服務(wù)器,其他的還可以提供正常的服務(wù)。
系統(tǒng)分級(jí),哪些系統(tǒng)對(duì)用戶來說比較重要,級(jí)別就會(huì)更高,我們就要花更多心思去保障,其他的相對(duì)差一些。
降低耦合,最近在架構(gòu)圈當(dāng)中流行一個(gè)詞叫康威定律(編者注:Conway’s law: Organizations which design systems […] are constrained to produce designs which are copies of the communication structures of these organizations),是指系統(tǒng)架構(gòu)是和公司組織架構(gòu)是有關(guān)系的。降低耦合也是如此,不要把系統(tǒng)搞得太復(fù)雜,你的組織和團(tuán)隊(duì)不要和太多的部門打交 道。優(yōu)化架構(gòu),讓系統(tǒng)的關(guān)系盡可能的簡(jiǎn)單、明確。這樣出現(xiàn)問范圍可控。
有損服務(wù)是什么意思呢?可以犧牲一些用戶體驗(yàn)來保證基本功能的可用。
系統(tǒng)架構(gòu)當(dāng)中,分以下幾點(diǎn)。
第一個(gè)是數(shù)據(jù)獨(dú)立,不允許跨系統(tǒng)訪問數(shù)據(jù)庫(kù)這個(gè)常識(shí)大家都懂,但是很多公司做不好,因?yàn)闆]有強(qiáng)有力的措施去控制。這種事情做起來 不太容易,需要管理或者說大家認(rèn)可才行,但是實(shí)際上是非常關(guān)鍵的,因?yàn)閿?shù)據(jù)如果不切分,系統(tǒng)很難切分,耦合就非常嚴(yán)重。時(shí)間長(zhǎng)了出了問題,你連誰寫的,誰 改的這個(gè)數(shù)據(jù)都不知道,那怎么辦?
第二點(diǎn)是集群分布,這個(gè)就不提了。
第三個(gè)是冗余部署。比如說電商業(yè)務(wù)是有波動(dòng)的,每天的上午11點(diǎn)或者是下午4、5點(diǎn)訂單量都會(huì)增長(zhǎng),上班族都要休息一下,給自己的辛苦找一些心理 安慰,這個(gè)時(shí)候開始購(gòu)物。但不能說就這點(diǎn)增長(zhǎng)就彈性部署一次。所以一定要有冗余,一般來講是3-5倍,保證哪怕突然來了一波流量你也可以扛得住。
尤其是電商公司,可能會(huì)搞一些促銷,可能有的業(yè)務(wù)部門搞促銷的時(shí)候,沒有知會(huì)技術(shù)部門,覺得這個(gè)促銷沒什么,可能一兩天就搞定了,然后流量預(yù)估也 就上來200%。但是萬一趕上這是網(wǎng)絡(luò)紅人、明星或者是小鮮肉出了書、發(fā)了唱片或者穿了什么衣服,一下子成了爆款,系統(tǒng)沒扛住,然后運(yùn)營(yíng)回頭就得抱怨白折 騰了。
第四個(gè)讀寫分離這個(gè)不用說了。
技術(shù)架構(gòu)方面,仔細(xì)說一下。要是小公司出了什么問題,幾個(gè)人碰個(gè)頭,達(dá)成共識(shí)就可以了;但是一個(gè)上規(guī)模的公司,技術(shù)團(tuán)隊(duì)幾百人甚至是上千人的團(tuán)隊(duì),如果技術(shù)層面控制不了的話,就會(huì)有非常嚴(yán)重的隱患。
首先是選擇使用的技術(shù)平臺(tái),有的公司java也有、PHP也有、Python、Go等等的什么都有。
其次是人職能,有的公司說我們的工程師都要做全棧工程師,我們的工程師什么都會(huì)。創(chuàng)業(yè)團(tuán)隊(duì)可以,但是一般成熟的公司都是專業(yè)分工,專業(yè)分工就來了一個(gè)問題,大家畢竟要對(duì)接,而且很多東西需要有人持續(xù)運(yùn)維,因此就有必要統(tǒng)一技術(shù)標(biāo)準(zhǔn)。
第三點(diǎn)就是規(guī)范標(biāo)準(zhǔn),比如說代碼、發(fā)布的規(guī)范都要有。如果說可以沉淀的話,以上說的規(guī)范是可以做成一個(gè)統(tǒng)一的框架,現(xiàn)在當(dāng)當(dāng)也在做一個(gè)框架。
還有就是合理的選型,一方面不同特性的技術(shù)需要用到合適的場(chǎng)景當(dāng)中。另一方面不合適的技術(shù)選型一定要盡量堵住。因?yàn)楝F(xiàn)在很多同學(xué)都有非常高漲的學(xué)習(xí)熱情,新技術(shù)層出不窮。這樣的話很多人會(huì)犯一個(gè)「錘子心理」的錯(cuò)誤。
比如說我最近在當(dāng)當(dāng)上買了一本書,花了兩個(gè)月看完,然后趕上做一個(gè)項(xiàng)目,我就覺得自己很懂了,英雄有了用武之地。錘子心理是什么意思呢?他有了一個(gè)錘子,看誰都是釘子,就想敲敲。這種情況是要控制的。
也許這個(gè)技術(shù)不是不能用,但是不是增加系統(tǒng)的負(fù)擔(dān),公司能不能持續(xù)運(yùn)營(yíng)。比如招來一個(gè)牛人,這個(gè)牛人自己寫了一個(gè)框架,用了什么算法。用起來確實(shí)很好,但是過后牛人走了怎么辦?出了問題怎么辦?誰管?這種問題都是要慮的。
還有就是持續(xù)集成。我們要從技術(shù)層面去保證多數(shù)測(cè)試都可以覆蓋到,不能說換一個(gè)測(cè)試或者是換一個(gè)開發(fā)就經(jīng)常犯一些重復(fù)的低級(jí)錯(cuò)誤。
基礎(chǔ)架構(gòu)
在一個(gè)完整的系統(tǒng)當(dāng)中有一些和業(yè)務(wù)沒有關(guān)系的系統(tǒng),比如運(yùn)維平臺(tái)的存在,是為了降低運(yùn)維的風(fēng)險(xiǎn),同時(shí)也是為了提高效率,保證質(zhì)量。
比如統(tǒng)一監(jiān)控,那么大一個(gè)系統(tǒng)誰知道哪里有問題,哪里不正常,所以必須要統(tǒng)一監(jiān)控。
還有是壓測(cè)工具,比如雙十一,你有沒有信心?誰敢說?我們要進(jìn)行測(cè)試,壓測(cè)之后我們說5倍沒問題,10倍沒問題。但是不壓測(cè)誰敢說?
還有就是流量控制。常見是分流和限流,如果說有一個(gè)頁(yè)面訪問量太大,可以分到類似的頁(yè)面去,更大的時(shí)候我們只能限流。
電商系統(tǒng)架構(gòu)
這個(gè)圖是一個(gè)比較簡(jiǎn)單的電商系統(tǒng)架構(gòu),主要說說系統(tǒng)分層。最上面的點(diǎn)是展示,包括首頁(yè)、搜索、列表、活動(dòng)專題頁(yè)這些東西,這個(gè)展示其實(shí)都是用戶查 詢的,沒有操作,只要用戶可以看就可以了,這些數(shù)據(jù)是可以緩存,可以靜態(tài)化的,可以通過這樣的方式保證用戶訪問,可以把數(shù)據(jù)都緩存起來。比如說當(dāng)當(dāng)?shù)氖?頁(yè),是不依賴任何系統(tǒng)的,其他系統(tǒng)都掛了,首頁(yè)打開是沒有問題的,畢竟主站是最大的流量入口。
還有第二點(diǎn)就是交易系統(tǒng)。和訂單系統(tǒng)是上下游的關(guān)系,交易系統(tǒng)是生成訂單的,訂單系統(tǒng)是處理訂單的。交易系統(tǒng)的訂單數(shù)據(jù)是存在自己的數(shù)據(jù)庫(kù)當(dāng)中。 為什么呢?因?yàn)楹貌蝗菀子脩魜砹?,終于下單了,一定要留住。訂單系統(tǒng)也很復(fù)雜,不能說因?yàn)橛唵蜗到y(tǒng)掛了,導(dǎo)致訂單無法生成了。所以生成訂單這件事情是在交 易系統(tǒng)完成的。訂單系統(tǒng)可以異步去處理訂單,訂單系統(tǒng)出了問題,用戶該買還是可以買的,這是電商當(dāng)中非常重要的。
第三個(gè)是商品數(shù)據(jù)中心,就是為了應(yīng)對(duì)前面的這一堆面向用戶的訪問,我們的數(shù)據(jù)是單獨(dú)有一份只讀的對(duì)外提供,和后面的PIM系統(tǒng)是分開的。PIM是寫,這邊是讀。如果PIM掛了,沒有問題。后臺(tái)系統(tǒng)不會(huì)對(duì)前臺(tái)造成太大的影響。
交易系統(tǒng)是最核心的,最大的使命是生成訂單。除了基本的生成訂單的功能,還可以做什么呢?第一就是要快!比如說促銷,這里沒有寫價(jià)格和庫(kù)存,價(jià)格 和庫(kù)存都是敏感數(shù)據(jù),要求盡可能準(zhǔn)確的,我們都是實(shí)時(shí)的。但是促銷是可以緩存的,因?yàn)楝F(xiàn)在還不是系統(tǒng)智能去調(diào)整促銷策略的,都是靠人工設(shè)置的,節(jié)奏和頻率 都是比較低的,緩存下來之后,基本上是OK的。避免促銷服務(wù)不穩(wěn)定對(duì)交易產(chǎn)生影響,如果用戶點(diǎn)半天沒有反應(yīng),用戶就會(huì)走的,要降低依賴。
還有一個(gè)交易單緩存,就是訂單生成之前的臨時(shí)數(shù)據(jù),要選擇支付方式、要寫地址、要選擇是不是用紅包、抵用券、優(yōu)惠卡這些東西,選得差不多了,萬一 客戶端瀏覽器崩潰了、網(wǎng)斷了或者是閃斷、交易系統(tǒng)應(yīng)用服務(wù)器某一個(gè)節(jié)點(diǎn)掛了,怎么辦?這是最重要的時(shí)刻,都已經(jīng)臨門一腳了,我們是有緩存的,數(shù)據(jù)量也不是 很大,只要他在比較短的時(shí)間內(nèi)打開,填的東西還在,還可以順暢的往下走。這個(gè)也是非常重要的。我記得以前有的網(wǎng)站出了問題,要重新選一遍,那個(gè)時(shí)候覺得非 常郁悶,除非這個(gè)東西非常需要,否則那就算了。
電商數(shù)據(jù)模型
這是電商最常見的數(shù)據(jù)模型,商家來發(fā)布商品、設(shè)置促銷、價(jià)格、庫(kù)存這些東西。用戶來瀏覽、收藏、加入購(gòu)物車,最后下單。對(duì)于平臺(tái)電商來說,就會(huì)出現(xiàn)多個(gè)商家,商品要按照商家來分,訂單也要按照商家來分。但是對(duì)用戶來說,收藏、加購(gòu)物車的商品還有訂單對(duì)應(yīng)的是多個(gè)商家。
這個(gè)時(shí)候有一個(gè)非常明確的問題,比如查詢收藏列表,或者是商家管理他的商品的時(shí)候,怎么樣可以很快的處理?商品可能有幾千萬上億,肯定不會(huì)放在一個(gè)數(shù)據(jù)庫(kù)里,多個(gè)數(shù)據(jù)庫(kù),按什么分?后邊按商家分,前邊按用戶分,中間兩套數(shù)據(jù)庫(kù)。
說起來邏輯其實(shí)挺簡(jiǎn)單,但是很多創(chuàng)業(yè)公司沒有琢磨過這個(gè)事,中間就是一個(gè)庫(kù),上面設(shè)一個(gè)索引,數(shù)據(jù)量小還沒有問題,一旦大了怎么辦?覺得這是解決不了的問題。
進(jìn)一步來說,這只是一個(gè)場(chǎng)景,還有一些更具體的場(chǎng)景。比如說我們剛剛提到購(gòu)物車或者是收藏夾,如果在購(gòu)物車或者是收藏夾,商品數(shù)據(jù)不按照用戶來分,也不按照商家分,就按照商品ID來分,均勻的分布在我們的數(shù)據(jù)層是不是可行?
這個(gè)邏輯在平時(shí)也許沒有問題,但是電商有一個(gè)說法叫爆品,大家可以想像一下,平時(shí)是沒有問題的,正常下單正常瀏覽,一旦出現(xiàn)爆品,就會(huì)出現(xiàn)熱點(diǎn)數(shù) 據(jù)。爆品所在的數(shù)據(jù)分片會(huì)被用戶集中瀏覽,熱點(diǎn)問題沒有辦法解決就是設(shè)計(jì)缺陷。再怎么分,那一個(gè)商品就在一個(gè)庫(kù)當(dāng)中,你也不能把它一劈兩半。就是我剛剛說 的,可能突然爆發(fā)一下,時(shí)間也不長(zhǎng),但是你扛不住,扛不住怎么辦?我們一會(huì)兒再說。
資源隔離重點(diǎn)保障,這也是很重要的。比如商品數(shù)據(jù)中心給前臺(tái)提供商品數(shù)據(jù),是分成三個(gè)集群的。那邊的是網(wǎng)站,這邊是App,這邊是購(gòu)物車和交易, 各自都有自己的緩存和數(shù)據(jù)庫(kù),數(shù)據(jù)完全一樣的。為什么要分開?和剛剛說的一樣,首先交易下單是最關(guān)鍵的而且性能要保證,不能受到其他場(chǎng)景的影響。其次移動(dòng) 端也非常重要,大家都是在手機(jī)上操作,其實(shí)對(duì)速度是非常關(guān)注的,不能因?yàn)榫W(wǎng)站流量大了,導(dǎo)致手機(jī)瀏覽緩慢,甚至可以掛掉一個(gè)集群,其他的還正常,其實(shí)就是 不要把雞蛋放到一個(gè)籃子里。用空間換時(shí)間,用時(shí)間換空間。
通過框架來樹立開發(fā)規(guī)范
我們做的一個(gè)框架叫ddframe,這是我們技術(shù)層面想做的事情。很多的互聯(lián)網(wǎng)公司開發(fā)平均工作經(jīng)驗(yàn)有3就不錯(cuò)了。因?yàn)檫@幾各種創(chuàng)業(yè)公司比較 多,膨脹的也很厲害,要找一些有經(jīng)驗(yàn)的工程師很難。很多開發(fā)同學(xué)沒有經(jīng)歷過各種慘痛教訓(xùn),開發(fā)都是比較隨意的,因此我們需要做一個(gè)開發(fā)的框架去給他們做一 些規(guī)范的事,能夠有效的去幫助他們,盡量不去做一些出格的事情,因此我們做了ddframe。
框架有幾個(gè)模塊:包括最核心的部分、包括和監(jiān)控的對(duì)接、SOA的部分DubboX、還有作業(yè)框架elastic-job、以及分布式數(shù)據(jù)庫(kù)中間件sharding-JDBC。
Dubbox是我們?cè)贒ubbo的層面做了二次開發(fā),現(xiàn)在有不少公司在用,這個(gè)部分把一般的服務(wù)注冊(cè)、軟負(fù)載、路由都搞定了。
elastic-job是分布式作業(yè)調(diào)度框架。采用分布式作業(yè)調(diào)度框架前有什么問題呢?第一個(gè)是怎么實(shí)現(xiàn)避免單點(diǎn),很多人是這樣做的,兩臺(tái)機(jī)器都 部署,其中一臺(tái)crontab注釋一下,一臺(tái)機(jī)器出問題了,就去另外那臺(tái)機(jī)器上把注釋去掉,這是非常低效的,而且是完全靠人的。機(jī)器多了怎么辦?因此我們 需要分布式的作業(yè)調(diào)度。這是我們?nèi)ラ_發(fā)的,最近唯品會(huì)在我們的早期版本基礎(chǔ)上,自己做了一個(gè)內(nèi)部的作業(yè)調(diào)度平臺(tái),當(dāng)然也歡迎大家使用。我們?yōu)槭裁醋约?做,為什么不用TBSchedule,是因?yàn)槲覀儼l(fā)現(xiàn)沒有特別合適的,所以自己做。
第二個(gè)模塊就是RDB,就是分布式數(shù)據(jù)庫(kù)問題,和高可用關(guān)系不太大,不詳細(xì)介紹??傮w而言,我們是想通過統(tǒng)一的框架、技術(shù)組件降低開發(fā)人實(shí)現(xiàn)的復(fù)雜度,減少風(fēng)險(xiǎn),不給他們找麻煩。
有了框架就有了工具,有了工具就有了共同的語言。大家可以回想一下歷史課,秦始皇統(tǒng)一六國(guó)之后做了什么,統(tǒng)一度量衡、錢幣、文字。有了這些統(tǒng)一的 東西,大家互相之間比較容易交流、積累經(jīng)驗(yàn),如果說某個(gè)團(tuán)隊(duì)比較閑了,也可以支持別的團(tuán)隊(duì),有人在某個(gè)團(tuán)隊(duì)膩了,可以去其他的團(tuán)隊(duì)。
運(yùn)維與監(jiān)控
原來我們有一個(gè)運(yùn)維平臺(tái),但是去技術(shù)圈出現(xiàn)了那么多的各種事件,運(yùn)維經(jīng)理說運(yùn)維太重要也太危險(xiǎn)了,因此我們做了一個(gè)強(qiáng)制的生產(chǎn)環(huán)境灰度發(fā)布,不允許你一鍵發(fā)布,給大家一個(gè)緩沖。自動(dòng)備份也是非常重要的,如果說你發(fā)現(xiàn)灰度發(fā)布第一個(gè)節(jié)點(diǎn)就報(bào)錯(cuò)了,你要做的事情就是回滾。
接下來是監(jiān)控。監(jiān)控是一個(gè)很大的系統(tǒng),非常的重要。一個(gè)好的監(jiān)控系統(tǒng)可能更牛,因?yàn)榫退闶?4小時(shí)都有運(yùn)維的同學(xué),但是運(yùn)維同學(xué)也有打盹的時(shí)候, 或者是沒注意。經(jīng)常我們會(huì)在電影當(dāng)中看到,某一個(gè)大盜進(jìn)入到某一個(gè)大廈當(dāng)中,保安就在那里喝個(gè)茶什么的,保安沒看到。這種事情是經(jīng)常會(huì)有的。
而且有了監(jiān)控就有了數(shù)據(jù),監(jiān)控不一定觸發(fā)報(bào)警,但是你有了數(shù)據(jù)之后可以看趨勢(shì)。比如說最重要的一點(diǎn)–預(yù)算。我們今要采購(gòu)多少臺(tái)服務(wù)器,多數(shù)是拍腦袋拍出來的,業(yè)務(wù)說我們今業(yè)務(wù)量增加30%,我們多采購(gòu)30%的服務(wù)器,就是這么拍腦袋拍出來的,其實(shí)這個(gè)是不準(zhǔn)確的。
如果系統(tǒng)在某些場(chǎng)景下有嚴(yán)重的性能衰竭,需要去評(píng)估,或者要去看,不同的業(yè)務(wù)模式會(huì)對(duì)系統(tǒng)造成不同的壓力。比如有的系統(tǒng)今負(fù)載反而下降了,就往 下減服務(wù)器。有的可能增加200%,原來10%的負(fù)載,現(xiàn)在變成了30%了,那么這種,哪怕你的業(yè)務(wù)增長(zhǎng)30%,這個(gè)壓力還是增長(zhǎng)200%。這是什么概 念?之前是10%到30%,現(xiàn)在就是30%到90%了。你只有有了這些數(shù)據(jù),才可以合理的去估算。
大促或者出現(xiàn)爆品時(shí)怎么辦
相信在上海的同學(xué)也都遇到過這樣的情況。在地鐵站,高峰時(shí)限流,用欄桿把人擋住。限流基本上是電商標(biāo)配,以前沒有,所以動(dòng)不動(dòng)就掛了。現(xiàn)在成熟了,如果出現(xiàn)了爆品,出現(xiàn)了熱點(diǎn)數(shù)據(jù)怎么辦?
你不能說流量一來你就掛了,這個(gè)時(shí)候限流就非常重要了。舉例來說可以扛得住8000,8000以外的就攔住,不讓進(jìn)來。比如淘寶去雙十一零點(diǎn)之 后的幾分鐘,有人手機(jī)淘寶進(jìn)不去,或者是支付寶支付不了,就在朋友圈里發(fā)截圖說淘寶又掛了,但是沒有多少人回應(yīng),因?yàn)槎鄶?shù)人是可以使用的,他剛好倒霉,是 被限流了。有了限流今天來10倍就10倍,來20倍沒有辦法,但是系統(tǒng)扛得住,把其他的流量扔了,保證了基本的收入。
那么最后我們?cè)撟龅氖虑槎甲隽?,還能怎么辦呢?就只能求佛祖保佑了。這種時(shí)候有信仰也許會(huì)對(duì)你的系統(tǒng)可用性指標(biāo)有點(diǎn)幫助。不管有沒有用,我們可以努力一下,在自己的代碼注釋當(dāng)中放上一個(gè)佛祖保佑一下。
聲明:該框架面向企業(yè)的大型互聯(lián)網(wǎng)分布式企業(yè)架構(gòu),后期會(huì)介紹linux上部署高可用集群項(xiàng)目。有愿意了解框架技術(shù)或者源碼的朋友直接加Q(2137028325)一起學(xué)習(xí)
核心技術(shù):Maven,Springmvc mybatis shiro, Druid, Restful, Dubbo, ZooKeeper,Redis,FastDFS,ActiveMQ,Nginx
1. 項(xiàng)目核心代碼結(jié)構(gòu)截圖
項(xiàng)目模塊依賴
特別提醒:開發(fā)人在開發(fā)的時(shí)候可以將自己的業(yè)務(wù)REST服務(wù)化或者Dubbo服務(wù)化
2. 項(xiàng)目依賴介紹
2.1 后臺(tái)管理系統(tǒng)、Rest服務(wù)系統(tǒng)、Scheculer定時(shí)調(diào)度系統(tǒng)依賴如下圖:
2.2 Dubbo獨(dú)立服務(wù)項(xiàng)目依賴如下圖:
zookeeper、dubbo服務(wù)啟動(dòng)
dubbo管控臺(tái)
REST服務(wù)平臺(tái)
4. 平臺(tái)簡(jiǎn)介
Jeesz是一個(gè)分布式的框架,提供項(xiàng)目模塊化、服務(wù)化、熱插拔的思想,高度封裝安全性的Java EE快速開發(fā)平臺(tái)。
Jeesz本身集成Dubbo服務(wù)管控、Zookeeper注冊(cè)中心、Redis分布式緩存技術(shù)、FastDFS分布式文件系統(tǒng)、ActiveMQ異步消息中間件、Nginx負(fù)載均衡等分布式技術(shù)
使用Maven做項(xiàng)目管理,項(xiàng)目模塊化,提高項(xiàng)目的易開發(fā)性、擴(kuò)展性
以Spring Framework為核心容器,Spring MVC為模型視圖控制器,MyBatis為數(shù)據(jù)訪問層, Apache Shiro為權(quán)限授權(quán)層,Ehcahe對(duì)常用數(shù)據(jù)進(jìn)行緩存,Activit為工作流引擎等。
前端集成Bootstrap4 metronic框架,UI響應(yīng)式、扁平化布局,適應(yīng)所有PC、Pad、Anroid、ios 移動(dòng)設(shè)備等。
Jeesz主要定位于互聯(lián)網(wǎng)企業(yè)架構(gòu),已內(nèi)置企業(yè)信息化系統(tǒng)的基礎(chǔ) 功能和高效的代碼生成工具,包括:系統(tǒng)權(quán)限組件、數(shù)據(jù)權(quán)限組件、數(shù)據(jù)字典組件、核心工具 組件、視圖操作組件、工作流組件、代碼生成等。采用分層設(shè)計(jì)、雙重驗(yàn)證、提交數(shù)據(jù)安全編碼、密碼加密、訪問驗(yàn)證、數(shù)據(jù)權(quán)限驗(yàn)證。
Jeesz目前包括以下模塊項(xiàng)目,后臺(tái)系統(tǒng)管理系統(tǒng),RestFul獨(dú)立服務(wù)系統(tǒng)、Scheduler定時(shí)調(diào)度系統(tǒng)、內(nèi)容管理(CMS)系統(tǒng)、在線辦公(OA)系統(tǒng)、我的待辦(Task服務(wù))、我的收藏(Bookmark服務(wù))。
后臺(tái)管理系統(tǒng)包括企業(yè)組織架構(gòu)(用戶管理、機(jī)構(gòu)管理、區(qū)域管理)、菜單管理、角色權(quán)限管理、字典管理等功能;
RestFul獨(dú)立提供標(biāo)準(zhǔn)Rest服務(wù)API,您可以快速實(shí)現(xiàn)自己的業(yè)務(wù),提供需要的服務(wù);
Quartz定時(shí)調(diào)度系統(tǒng)可以動(dòng)態(tài)配置您的任務(wù)規(guī)則等;
內(nèi)容管理(CMS)系統(tǒng),包括內(nèi)容管理,欄目管理、站點(diǎn)管理、公共留言、文件管理、前端網(wǎng)站展示等功能;
在線辦公(OA)系統(tǒng),主要提供簡(jiǎn)單的流程實(shí)例。
Jeesz提供了常用工具進(jìn)行封裝,包括日志工具、緩存工具、服務(wù) 器端驗(yàn)證、數(shù)據(jù)字典、當(dāng)前組織機(jī)構(gòu)數(shù)據(jù)(用戶、機(jī)構(gòu)、區(qū)域)以及其它常用小工具等。另外 還提供一個(gè)強(qiáng)大的在線 代碼生成 工具,此工具提供簡(jiǎn)單的單表、一對(duì)多、樹結(jié)構(gòu)功能的生成,如果對(duì)外觀要求不是很高,生成的功能就可以用了。使用了Jeesz基礎(chǔ)框架,可以提高快速開發(fā)效 率。
5. 內(nèi)置功能(只列了一部分功能)
1.用戶管理:用戶是系統(tǒng)操作者,該功能主要完成系統(tǒng)用戶配置。
2.機(jī)構(gòu)管理:配置系統(tǒng)組織機(jī)構(gòu)(公司、部門、小組),樹結(jié)構(gòu)展現(xiàn),可隨意調(diào)整上下級(jí)。
3.區(qū)域管理:系統(tǒng)城市區(qū)域模型,如:國(guó)家、省市、地市、區(qū)縣的維護(hù)。
4.菜單管理:配置系統(tǒng)菜單,操作權(quán)限,按鈕權(quán)限標(biāo)識(shí)等。
5.角色管理:角色菜單權(quán)限分配、設(shè)置角色按機(jī)構(gòu)進(jìn)行數(shù)據(jù)范圍權(quán)限劃分。
6.字典管理:對(duì)系統(tǒng)中經(jīng)常使用的一些較為固定的數(shù)據(jù)進(jìn)行維護(hù),如:是否、男女、類別、級(jí)別等。
7.操作日志:系統(tǒng)正常操作日志記錄和查詢;系統(tǒng)異常信息日志記錄和查詢。
8.連接池監(jiān)視:監(jiān)視當(dāng)期系統(tǒng)數(shù)據(jù)庫(kù)連接池狀態(tài),可進(jìn)行分析SQL找出系統(tǒng)性能瓶頸。
9.工作流引擎:實(shí)現(xiàn)業(yè)務(wù)工單流轉(zhuǎn)、在線流程設(shè)計(jì)器。
6. 開發(fā)工具
1.Eclipse IDE:采用Maven項(xiàng)目管理,模塊化。
2.代碼生成:通過界面方式簡(jiǎn)單配置,自動(dòng)生成相應(yīng)代碼,目前包括三種生成方式(增刪改查):?jiǎn)伪?、一?duì)多、樹結(jié)構(gòu)。生成后的代碼如果不需要注意美觀程度,生成后即可用。
7. 技術(shù)選型(只列了一部分技術(shù))
1、后端
服務(wù)框架:Dubbo、zookeeper、Rest服務(wù)
緩存:Redis、ehcache
消息中間件:ActiveMQ
負(fù)載均衡:Nginx
分布式文件:FastDFS
數(shù)據(jù)庫(kù)連接池:Alibaba Druid 1.0
核心框架:Spring framework
安全框架:Apache Shiro 1.2
視圖框架:Spring MVC 4.0
服務(wù)端驗(yàn)證:Hibernate Validator 5.1
布局框架:SiteMesh 2.4
工作流引擎:Activiti 5.15
任務(wù)調(diào)度:quartz 1.8.5
持久層框架:MyBatis 3.2
日志管理:SLF4J 1.7、Log4j
工具類:Apache Commons、Jackson 2.2、Xstream 1.4、Dozer 5.3、POI
2、前端
JS框架:JQuery 1.9。
CSS框架: Bootstrap 4 metronic
客戶端驗(yàn)證:JQuery Validation Plugin。
富文本:CKEcitor
文件管理:CKFinder
動(dòng)態(tài)頁(yè)簽:Jerichotab
數(shù)據(jù)表格:jqGrid
對(duì)話框:jQuery jBox
樹結(jié)構(gòu)控件:jQuery zTree
其他組件:Bootstrap 4 metronic
3、支持
服務(wù)器中間件:Tomcat 6、7、Jboss 7、WebLogic 10、WebSphere 8
數(shù)據(jù)庫(kù)支持:目前僅提供mysql數(shù)據(jù)庫(kù)的支持,但不限于數(shù)據(jù)庫(kù),下個(gè)版本升級(jí)多數(shù)據(jù)源切換和數(shù)據(jù)庫(kù)讀寫分離: 如:Oracle、SqlServer、H2等
支持開發(fā)環(huán)境:Eclipse、MyEclipse、Ras、Idea等
聯(lián)系客服