系統架構模式

一、什么是架構

架構就是骨架
人類的身體的支撐是主要由骨架來承擔的,然后是其上面的肌肉、神經、皮膚。架構對于軟件的重要性不亞于骨架對人類身體的重要性。

二、8種架構模式

1、單庫單應用模式

這是最簡單的一種設計模式,在初學和小項目中常見


image.png

如上圖所示,這種模式一般只有一個數據庫,一個業務應用層,一個后臺管理系統,所有的業務都是用業務層完成的,所有的數據也都是存儲在一個數據庫中。

優點:結構簡單、開發速度快、實現簡單,可用于產品的第一版等有原型驗證需求。

缺點:性能差、擴展性差,不適合用于大規模部署、應用等生產環境。

2、讀寫分離模式

這種模式主要解決單及數據庫壓力過大,從而導致業務緩慢甚至超時,查詢影響時間變長的問題,也包括需要大量數據庫服務器計算資源的查詢請求,這個可以說是單庫應用模式的升級版本,也是技術架構迭代演進過程中的必經之路。


image.png

這種模式較單庫但應用模式與內容分發模式多了幾個部分,一個是業務數據庫的主從分離,一個是引入ES,為什么要這樣?都解決的哪些痛點,下面具體結合業務需求場景進行敘述。

場景一:關鍵詞檢索

這個需求在大部分的系統中都會存在,如果使用傳統的數據庫技術,大部分可能會使用like這種sql語句。sql語句的性能問題與全表掃描機制導致了非常嚴重的性能問題,現在基本上很少見到。故采用ES作為搜索引擎。

場景二:大量的普通查詢

這個場景是指我們的業務中的大部分輔助性的查詢,如:取錢的時候先查詢一下余額,根據用戶的ID查詢用戶的記錄,取得該用戶最新的一條取錢記錄等,我們肯定是要天天用到的,而且用的還非常多。同時呢,我們的寫入請求也是非常多的,導致大量的寫入、查詢操作壓向同一數據庫,然后,數據庫撐不住掛掉。

所以要求我們必須分散數據庫的壓力,一個業界較成熟的方案就是數據庫的讀寫分離,寫的時候入主庫,讀的時候讀分庫。這樣就把壓力分散到不同的數據庫了,如果一個讀庫性能不行,扛不住的話,可以一主多從,橫向擴展。

  • 請求數據庫存儲在主庫中
  • 數據同步或異步存入從庫中
  • 讀取數據時直接從讀庫讀取數據

延遲問題?
如:數據還沒到從庫,我就馬上讀,那么是讀不到的,會發生問題的。對于這個問題,各家公司解決的思路也是不一樣的,方法不盡相同,一個普遍的解決方案是:讀不到就讀主庫

優點:減少數據庫的壓力,理論上提供無限高的讀性能,提高業務(寫)的性能。

缺點:數據延遲,數據一致性的保證。

3、內容分發模式

基本上所有的大型的網站都有或多或少的采用這一種設計模式,常見的應用場景是采用CDN技術把網頁、圖片、CSS、JS等這些靜態資源分發到離用戶最近的服務器


image.png

這種模式較單庫單應用的模式多了一個CDN、一個云存儲OSS。一個經典的應用流程(以用戶上傳、查看圖片需求為例如下:)

1、上傳的時候,用戶選擇本地機器上的一個圖片進行上傳

2、程序會把這個圖片上傳到云存儲OSS上,并返回該圖片的一個URL

3、程序把這個URL字符串存儲在業務數據庫中,上傳完成

4、查看的時候,程序從業務數據庫得到該圖片的URL

5、程序通過DNS查詢到這個URL的圖片服務器

6、智能DNS會解析這個URL,得到于用戶最近的服務器(或集群)的地址A

7、然后把服務器A上的圖片返回給程序

8、程序顯示該圖片,查看完成

由上可知,這個模式的關鍵是智能DNS,它能夠解析出離用戶最近的服務器,運行原理大致是:根據請求者的IP得到請求地點B,然后通過計算或者配置得到與B最近或通訊時間最短的服務器C,然后把C的IP地址返回給請求者。這種模式的優缺點如下:

優點:資源下載快,無需過多的開發與配置,同時也減輕了后端服務器對資源的存儲壓力,減少帶寬的使用。

缺點:目前來說OSS、CDN的價格還是稍微有點貴的,只適用于中小規模的應用,另外由于網絡傳輸延遲、CDN的同步策略等,會有一些一致性、更新慢方面的問題。

4、微服務模式

為什么要使用微服務?
1、單及數據庫寫請求量大量增加,導致數據庫壓力變大
2、數據庫一旦掛了,那么整個業務都掛了
3、業務代碼越來越多,都在一個GIT里,越來越難以維護
4、代碼腐化嚴重,臭味越來越濃
5、上線越來越頻繁,經常是一個小功能的修改,就要整個大項目重新編譯
6、部門越來越多,該哪個部門改動大項目中的哪個東西,撕逼的厲害
7、其他一些外圍系統直接連數據庫,導致一旦數據庫結構發生變化,所有的相關系統都要通知,甚至對修改不敏感的系統也要通知
8、每個應用服務器需要開通所有權限、網絡、FTP、各種各樣的,因為每個服務器部署的應用都是一樣的。


image.png

如上圖所示,把業務分塊,做了垂直切分,切成一個個獨立的系統,每個系統各自衍化,有自己的庫、緩存、ES等輔助系統,系統之間的實時交互通過RPC/Rest API,異步交互通過MQ,通過這種組合,共同完成整個系統功能。

那么,這么做是否真的能解決上述問題了呢?不玩虛的,一個一個來說。

對于問題一,由于拆分成多個子系統,系統的壓力被分散了,而各個子系統都有自己的數據庫實例,所以數據庫的壓力變小。

對于問題二,一個子系統A的數據庫掛了,只是影響到系統A和使用系統A的那些功能,不會所有的功能不可用,從而解決一個數據庫掛了,導致所有的功能都不可用的情況。

對于問題三、四,也因為拆分得到了解決,各個子系統都有自己獨立的GIT代碼庫,不會相互影響。通用的模塊可通過庫、服務、平臺的形式解決。

對于問題五,子系統A發生改變,需要上線,那么我們只需要編譯A,然后上線就可以了,不需要其他系統做通向的事情。

對于問題六,順應了康威定律,我部門該干什么事,輸出什么,也通過服務的形式暴露出來,我部門只管把我部的職責、軟件功能做好就可以。

對于問題七,所有需要我部數據的需求,都通過接口的形式發布出去,客戶通過接口獲取數據,從而屏蔽了底層數據庫結構,甚至數據來源,我部只需保證我部的接口契約沒有發生變化即可,新的需求增加新的接口,不會影響老的接口。

對于問題八,不同的子系統需要不同的權限,這個問題也優雅的解決了。

優點:相對高性能,可擴展性強,高可用,適用于中等以上規模公司架構。

缺點:復雜、度不好把握。指不僅需要一個能在高層把控大方向、大流程、總體技術的人,還需要能夠針對各個子系統有針對性的開發。把握不好度或者濫用的話,這個模式適得其反!

5、多級緩存模式

這個模式可以說是應對超高查詢壓力的一種普遍采用的策略,基本的思想就是在所有鏈路的地方,能加緩存的就加緩存,如下圖所示:


image.png

如上圖所示,一般在三個地方加入緩存,一個是客戶端處,一個是API網關處,一個是具體的后端業務處,下面分別介紹:

客戶端處緩存:這個地方加緩存可以說是效果最好的一個——無延遲。因為不用經過長長的網絡鏈條去后端業務處獲取數據,從而導致加載時間過長,客戶流失等損失,雖然有CDN的支持,但是從客戶端到CDN還是有網絡延遲的,雖然不大,具體的技術依據不同的客戶端而定,對于WEB來講,有瀏覽器本地緩存、Cookie、Storage、緩存策略等技術;對于APP來講,有本地數據庫,本地文件,本地內存,進程內緩存支持,以上提到的各種技術有興趣的同學可以繼續展開學習,如果客戶端緩存沒有命中,那么會去后端業務拿數據,一般來講,就會有個API網關,在這里加緩存也是非常重要的。

后端業務處理:這個我就不用多說了,大家應該差不多都知道,什么Redis、Memcache、Jvm等等,不贅述了。

實踐中,要結合具體的實際情況,綜合利用各級緩存技術,使得各種請求最大程度的在到達后端業務之前就被解決掉,從而減少后端服務器壓力、減少占用帶寬、增強用戶體驗。至于是否只有這三個地方加緩存,我覺得要活學活用,心法比劍法重要!總結一下這個模式的優缺點:

優點:抗住大量讀請求,減少后端壓力。

缺點:數據一致性問題較為突出,容易發生雪崩,即:如果客戶端緩存失效、API網關緩存失效,那么所有的大量請求瞬間壓向后端業務系統,后果可想而知。

6、分庫分表模式

這種模式主要解決單表寫入、讀取 、存儲壓力過大,從而導致業務緩慢甚至超時,交易失敗,容量不夠的問題。一般有水平切分和垂直切分兩種,這里主要介紹水平切分。這個模式也是技術架構迭代演進的必經之路。


image.png

如上圖所示紅色部分,把一張表分到了幾個不同的庫中,從而分擔壓力。是不是很籠統?哈哈,那我們接下來就詳細的講解一下,首先澄清幾個概念,如下:

主機:硬件,指一臺物理機,或虛擬機,有自己的CPU,內存,硬盤等。

實例:數據庫實例,如一個MySql服務進程,一個主機可以有多個實例,不同的實例有不同的進程,監聽不同的端口。

庫:指表的集合,如學校庫,可能包含教師表、學生表、食堂表等等,這些表在一個庫中。一個實例中可以有多個庫,庫與庫之間用庫名來區分。

表:庫中的表,不必多說,不懂的就不用往下看了,不解釋。

那么怎么把單表分散呢?到底怎么個分發呢?分發到哪里呢?以下是幾個工作中的實踐,分享一下:

主機:這是最主要的也是最重要的點,本質上分庫分表是因為計算與存儲資源不夠導致的,而這種資源主要由物理機,主機提供的,畢竟沒有可用的計算資源,怎么分效果都不是太好。

實例:實例控制著連接數,同時受OS限制,CPU、內存、硬盤、網絡IO也會受間接影響。會出現熱實例的現象,即:有些實例特別忙,有些實例非常的空閑。一個典型的現象是:由于單表反應慢,導致連接池被拉滿,所以其他的業務都受影響了。這時候,把表分到不同的實例是有一些效果的。

庫:一般是由于單庫中最大單表數量的限制,才采取分庫。

表:單表壓力過大,索引量大,容量大,單表的鎖。據以上,把單表水平切分成不同的表。

大型應用中,都是一臺主機上只有一個實例,一個實例中只有一個庫,庫==實例==主機,所以才有了分庫分表這個簡稱。

既然知道了這個基本理論,那么具體是怎么做的呢?邏輯是怎么跑的呢?接下來以一個例子來講解一下。

這個需求很簡單,用戶表(user),單表數據量1億,查詢、插入、存儲都出現了問題,怎么辦呢?

首先,分析問題,這個明顯是由于數據量太大了而導致的問題。

其次,設計方案,可以分為10個庫,這樣每個庫的數據量就降到了1KW,單表1KW數據量還是有些大,而且不利于以后量的增長,所以每個庫再分100個表,這樣每個單表數據量就為10W了,對于查詢、索引更新、單表文件大小、打開速度,都有一些溢出。接下來,給IT部門打電話,要10臺物理機,擴展數據庫……

最后,邏輯實現,這里應該是最有學問的地方。首先是寫入數據,需要知道寫到哪個分庫分表中,讀也是一樣的,所以,需要有個請求路由曾,負責把請求分發、轉換到不同的庫表中,一般有路由規則的概念。

怎么樣,簡單吧?哈哈。說說這個模式的問題,主要是帶來了事務上的問題,因為分庫分表,事務完成不了,而分布式事務又太笨重,所以這里需要有一定的策略,保證在這種情況下事務能夠完成。采取的策略如:最終一致性、復制、特殊設計等。再有就是業務代碼的改造,一些關聯查詢要改造,一些單表orderBy的問題需要特殊處理,也包括groupBy語句,如何解決這些副作用不是一句兩句能夠說清楚的,以后有時間,我單獨講講這些。

該總結一下這種模式的優缺點了,如下:

優點:減少數據庫單表的壓力。

缺點:事務保證困難、業務邏輯需要做大量改造。

7、彈性伸縮模式

這種模式主要解決突發流量的到來,導致無法橫向擴展或者橫向擴展太慢,進而影響業務,全站崩潰的問題。這個模式是一種相對來說比較高級的技術,也是各大公司目前都在研究、試用的技術。


image.png

如上圖所示,多了一個彈性伸縮服務,用來動態的增加、減少實例。原理上非常簡單,但是這個模式到底解決了什么問題呢?先說說由來和意義。

每年的雙11、618或者一些大促銷到來之前,我們都會為大流量的到來做以下幾個方面的工作:提前準備10倍甚至更多的機器,即便用不上也要放在那里備著,以防萬一,這樣浪費了大量的資源。每臺機器配置、調試、引流,以便讓所有的機器都可用,這樣浪費了大量的人力、物力,更容易出錯。如果機器準備不充分,那么還要加班加點的重復上面的工作,這樣特別容易出錯,引來領導的不滿,沒時間回家陪老婆,然后你老婆就……哈哈

在雙十一之后,我們還要人工做縮容,非常的辛苦。一般一年中會有多次促銷,那么我們就會一直這樣,實在是煩!

最嚴重的,突然間的大流量爆發,會讓我們猝不及防,半夜起來擴容是正常不過的事情,為此,我們偷懶起來,要更多的機器備著,也就出現了大量CPU利用率為1%的機器。

相信我,如果你是老板一定很震驚吧!

哈哈,那么如何改變這種情況呢?請接著看

為此,首先把所有的計算資源整合成資源池的概念,然后通過一些策略、監控、服務,動態的從資源池中獲取資源,用完后再放回到池子中,供其他系統使用。具體實現上比較成熟的兩種資源池方案是VM、docker,每個都有著自己強大的生態。監控點有CPU、內存、硬盤、網絡IO、服務質量等,根據這些,再配合一些預留、擴張、收縮策略,就可以簡單的實現自動收縮。怎么樣?是不是很神奇?深入的內容我會在后面的文章中詳細的講述,該總結以下這種模式的優缺點了。如下:

優點:彈性、隨需計算,充分優化企業計算資源。

缺點:應用要從架構層做到可橫向擴展化改造、依賴的底層配套比較多,對技術水平、實力、應用規模要求比較高。

8、多機房模式

這種模式主要解決不同地區高性能、高可用的問題

隨著應用用戶的不斷增加,用戶群體分布在全球各地,如果把服務器都部署在一個地方,一個地方,比如北京,那么美國的用戶使用應用的時候會特別慢,因為每個請求都需要通過海底光纜走上那么一秒鐘左右,這樣對用戶體檢及其不好,怎么辦?使用多機房部署。

用戶請求一個連接A

通過DNS智能解析到離用戶最近的機房B

使用B機房服務連接A

是不是覺得很簡單,沒啥?其實這里面的問題沒有表面這么簡單,下面一一道來,

首先是數據同步問題,在中國產生的數據要同步到美國,美國的也一樣,數據同步就會涉及數據版本、一致性、更新丟棄、刪除等問題。

其次是一地多機房的請求路由問題,典型的是如上圖,中國的北京機房和杭州機房,如果北京機房掛了,那么要能夠通過路由把所有發往北京機房的請求轉發到杭州機房,異地也存在這個問題。

友情鏈接
http://www.lxweimin.com/p/4046165b0387

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容

  • 一、什么是架構 我想這個問題,十個人回答得有十一個答案,因為另外的那一個是大家妥協的結果。哈哈,我理解,架構就是骨...
    風平浪靜如碼閱讀 653評論 0 1
  • 在上篇文章中,主要說了架構設計模式中的兩種,既:單庫單應用模式、內容分發模式,接下來介紹另外三種架構模式,分別為:...
    碼農原創閱讀 571評論 0 7
  • 面向對象技術為軟件技術帶來新的發展。人們運用面向對象的思想分析系統 、 為系統建模并設計系統,最后使用面向對象的程...
    deniro閱讀 541評論 0 2
  • 表情是什么,我認為表情就是表現出來的情緒。表情可以傳達很多信息。高興了當然就笑了,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 125,536評論 2 7
  • 16宿命:用概率思維提高你的勝算 以前的我是風險厭惡者,不喜歡去冒險,但是人生放棄了冒險,也就放棄了無數的可能。 ...
    yichen大刀閱讀 6,074評論 0 4