【寫在最前】
我們在平時的編程學習中,經常會接觸到“ 系統架構設計 ”這個概念;
但是很多小白并不能準確理解這個概念,以及常用系統的架構演進過程,甚至是在查閱了很多資料之后仍然是云山霧罩。
通過本文知識,讓我們花5分鐘時間徹底搞懂它,相信聰明的你,看完一定會有收獲!

【正文開始】
什么是架構設計模式?
我想這個問題,如果有5個人回答,估計能得出6個答案,因為第6個就是大家互相討論(妥協)的結果(^_^)。
在我看來,設計模式就是設計經驗,只有具備了足夠多的經驗,才能夠根據業務自身的具體情況,組合出最適合當前業務的架構設計,從而控制投入成本,提高工作效率。
筆者在IT行業深耕十余年,經歷過的架構設計(演進)可以說數以百計,今天把一些架構設計模式的一些經驗分享給大家,以饗讀者。
當前業界的架構設計,大體上可以分為 6種:
1. 單庫單應用模式
這種模式一般只有一個數據庫,一個后臺管理系統(當然也可以有前臺應用)。
這是最簡單的架構設計模式,也是所有IT初學者最先(必須)接觸到的模式。
說一下該模式的優缺點:
優點:結構簡單、開發速度快、實現簡單,可用于產品的第一版原型驗證需求、用戶少的設計。
缺點:性能差、沒有解決“高并發,高可用、大數據、易擴展“的問題(所以不能用于正式業務的生產環境)
注1:該架構是其他架構設計模式的基礎(再復雜的架構,也都是在這個模式上不斷演進的)
注2:目前流行的前后端分離模式,只是將前端工程化,但本質上并沒有改變應用架構的本質,所以在本文中仍然歸類為這一種。
2、內容分發模式
這種模式主要解決”靜態資源(網頁,圖片,js,css等)的訪問性能問題”
與單庫單應用模式相比:多了一個OSS云存儲(阿里云,七牛云等)和一個CDN加速網絡
CDN加速原理:
1)程序通過調用OSS上傳接口,得到圖片訪問地址U,并把U地址入庫
2)CDN網絡會將真實圖片資源,在各個CND節點緩存一份;
3)用戶訪問地址U時,CDN先拿到用戶端IP,然后再通過一個DNS智能查詢算法,找出與該用戶距離最近(或通訊時間最短)的CDN節點服務器,將該服務器的緩存圖片下發給用戶。
說一下該模式的優缺點:
優點:資源下載快、無需過多的開發與配置,同時也減輕了后端服務器對資源的存儲壓力,減少帶寬的使用。
缺點:目前來說OSS,CDN的價格還是稍微有些貴,只適用于中小規模的應用,另外由于網絡傳輸的延遲、CDN同步策略等,會有數據不一致的問題。
3、查詢分離模式
這種模式主要解決“查詢性能問題”.
這個可以說是單庫單應用模式的升級版本,也是架構迭代演進過程中的必經之路。
與單庫單應用模式相比:進行了業務數據庫的主從分離,并引入了ES搜索引擎
為什么要這樣做呢?下面結合兩個業務需求場景進行敘述。
場景一:業務讀多寫少
有統計數據表明,一般的業務系統,讀(查詢)場景跟寫(保存)場景的比例在7;3(甚至8:2)以上
這就決定了我們的系統中會有大量的查詢請求。
如果僅僅是因為數據庫的寫性能遇到了問題,而導致我們的系統80%的讀場景不可用,這顯然是不能夠接受的。
針對此問題,業界較為成熟的方案就是對數據庫進行”讀寫分離“,即寫的時候入主庫,讀的時候讀從庫。
這樣就把壓力分散到不同的數據庫了,如果一個讀庫性能不行,扛不住的話,可以一主多從,橫向擴展。
一般的業務流程是這樣的:
1)服務端把一條業務數據,寫到主數據庫(master)
2)主數據庫通過”同步策略“將該數據同步到從庫中(slave)
3)需要數據查詢時,直接去從庫(slave)讀相應的數據
一些聰明的、愛思考、想上進的同學可能發現問題了:就是數據的延遲問題,
比如:數據還沒有同步到從庫,我就馬上讀,那么肯定是讀不到的。
對于這個問題,各家公司解決的思路不一樣,方法也就不盡相同。
比如其中一個解決方案是:先嘗試讀從庫,如果讀不到就再嘗試讀主庫。
場景二:關鍵詞全文檢索
業務系統都會有關鍵字搜索的需求,如果使用傳統的數據庫技術,基本都會使用like這種SQL語句。
眾所周知:當數據量達到一定級別,SQL全表掃描會有嚴重的性能問題。
解決辦法就是全文檢索場景直接走ES搜索引擎(ES不僅可以替代數據庫完成全文檢索功能,還可以實現諸如分頁、排序、分組等功能)
ES搜索引擎的一般使用流程為,
1)服務端把一條業務數據落業務庫,同時異步發送給ES
2)ES把該條記錄按照預定規則、配置放入自己的索引庫
3)客戶端查詢時,由服務端把這個請求發送到ES,ES根據需求拼裝、組合數據,返回給客戶端
說完了兩個場景,該總結一下這種設計模式的優缺點的了:
優點:減少數據庫的壓力,理論上提供無限高的讀性能,間接提高業務(寫)的性能,專用的查詢、索引、全文(分詞)解決方案。
缺點:數據延遲,數據一致性的保證和解決。
4、分庫分表模式
這種模式主要解決"單表寫入壓力過大的問題",這個模式也是架構迭代演進過程中的必經之路。
對于單個業務表,一般有水平切分和垂直切分兩種,這里主要介紹水平切分。
理論上:一臺主機可以有多個實例,一個實例中可以有多個庫,一個庫可以有多個表。
實踐中:一臺主機上只有一個實例,一個實例中只有一個庫,庫==實例==主機,所以才有了分庫分表這個簡稱。
接下來以一個例子來講解一下分表流程:
假設用戶表(user),數據量有1億用戶,查詢、插入、存儲都出現了問題,怎么分呢?
首先,分析問題,這個明顯是由于數據量太大了而導致的問題。
其次,設計方案,可以分為10個庫,這樣每個庫的數據量就降到了1KW,單表1KW數據量還是有些大,而且不利于以后量的增長,所以每個庫再分100個表,這個每個單表數據量就為10W了,對于查詢、索引更新、單表文件大小、打開速度,都有益處。
再次,給IT運維部門打電話,要10臺物理機,擴展數據庫...... 最后,邏輯實現,這里是最有學問的地方。首先是寫入數據,需要知道寫到哪個分庫分表中,讀也是一樣的,所以,需要有個請求路由層,負責把請求分發、轉換到不同的庫表中,
說說這個模式的問題:
1)事務問題
因為分庫分表,傳統事務完成不了,而分布式事務又太笨太重,所以這里需要有一定的策略,保證在這種情況下事務能夠完成。常用的策略如:最終一致性、復制、特殊設計等。
2)關聯和分組查詢改造
該模式下,傳統的 join, orderby,grouby 都不能再用了,需要在業務代碼層進行改造。(如何解決這些副作用不是一句兩句能說清楚的,以后會單獨開篇,敬請及時關注作者)
該總結一下這種模式的優缺點的了,如下:
優點:減少數據庫單表的讀寫壓力。
缺點:事務保證困難、業務邏輯需要做大量改造。
5、微服務架構模式
上面的模式看似不錯,但也只是解決了部分性能問題。但是軟件系統天生的復雜性,決定了還有其他諸如”高可用、健壯性、易擴展“等大量問題等待我們去解決.
微服務模式 可以說是最近的熱點,花花綠綠、大大小小、國內國外的公司都在鼓吹,實踐這個模式,可是大部分都沒有弄清楚為什么要這么做,也并不知道這么做有什么好處、壞處,
在這里,我以自己的親身實踐說一下我對這個模式的看法,也請大家在評論區踴躍留言!
隨著項目發展,業務與人員的規模會不斷增加,從而會陸續遇到了如下問題:
1)數據庫寫壓力大量增加,導致數據庫不堪重負, 數據庫一旦掛了,那么整個系統業務都掛了
2)業務代碼越來越多,全都放在一個GIT里,越來越難以維護
3)上線要求越來越頻繁,經常是一個小功能的修改,就要整個大項目要重新編譯
4)其他一些外圍系統直接連接數據庫,導致一旦數據庫結構發生變化,所有的相關系統都要通知,甚至對修改不敏感的系統也要通知
5)每個應用服務器需要開通所有的、相同的、訪問權限和網絡權限,因為每個服務器部署的應用都是一樣的
慢慢的,所有人,都已經失去了對這個系統的把控......
微服務架構,就是為了解決上述這些問題,這種模式的一般設計見下圖:

如上圖所示,我們把業務分塊做了垂直切分,切成一個個獨立的業務系統,每個系統各自衍化,有自己的業務庫、緩存庫等,
系統之間的實時交互通過RPC遠程調用,異步交互通過MQ消息隊列
通過這種組合,共同完成整個系統功能。
這樣,對于上面的5個問題,我們就都有了解決方案:
對于問題1:由于拆分成了多個子系統,系統的壓力被分散了,而各個子系統都有自己的數據庫實例,所以數據庫的壓力變小。
一個子系統A的數據庫掛了,只是影響到系統A和使用系統A的那些功能,不會所有的功能不可用,從而可以解決一個數據庫掛了,導致所有功能不可用的問題。
對于問題2:各個子系統有自己獨立的GIT代碼庫,不會相互影響。通用的模塊可通過庫、服務、平臺的形式解決。
對于問題3:子系統A發生改變,需要上線,那么我只需要編譯A,然后只上線部署A就可以了,不需要其他系統做同樣的事情。
對于問題4:所有需要訪問的業務數據,都通過接口的形式發布出去,客戶通過接口獲取數據,從而屏蔽了底層數據庫結構。我們只需保證接口契約沒有發生變化即可,新的需求增加新的接口
對于問題5: 不同的子系統需要不同的權限,這個問題也優雅的解決了。
目前來看,所有問題都得到了解決???
注意:采用該架構,會有許多其他副作用隨之產生,如RPC、MQ的超高穩定性、超高性能,網絡延遲,數據一致性等問題,這里就不展開來講了,太多了,一本書都講不完。
另外:對于這個模式來說,最難把握的是拆分的維度,細粒度
一個較為可行的拆分指導原則是:能不分就不分,除非有非常必要的理由!
該總結一下這種模式的優缺點的了,如下:
優點:相對高性能,可擴展性強,高可用,適合于中等以上規模公司架構。
缺點:復雜、粒度不好把握。不僅需要一個能在高層把控大方向、大流程、總體技術的人,還需要能夠針對各個子系統有針對性的開發。把握不好度或者濫用的話,投入產出會適得其反!
6、彈性伸縮模式
這種模式主要解決流量高并發(流量突發)的問題。
比如:天貓雙11或京東618,會在特定的時間帶來巨大流量,但是傳統橫向擴展方案實施又比較慢,如果設計處理不好就會影響業務,甚至全站崩潰。
這個模式是一種相對來說比較高級的技術,也是各個大公司目前都正在研究、試用的技術。
時至今日,有這種思想的架構師就已經是算是很不錯了,更別提那些已經動手實踐過的,所以,你懂得......
與微服務模式相比,這種架構會多出一個“彈性伸縮服務”,用來動態的增加、減少實例。
具體實現上,比較成熟的兩種資源池方案是VM、Docker,每個產品目前都有著自己強大的生態。監控的點有CPU、內存、硬盤、網絡IO、服務質量等,根據這些,在配合一些預留、擴張、收縮策略,就可以簡單的實現自動伸縮。
該總結一下這種模式的優缺點的了,如下:
優點:彈性、隨需計算,充分優化企業計算資源。
缺點:應用要從架構層做到可動態配置的橫向擴展,彈性伸縮改造、依賴的底層配套比較多,對團隊的技術水平、運維實力、應用規模要求都非常高。
【全文完】






