在上篇文章中,介紹了八種架構設計模式中的兩種,既:單庫單應用模式、內容分發模式,沒有讀過的同窗請手動微信關注「碼農原創」公衆號,在歷史消息中尋找。接下來繼續介紹三種架構模式,分別是:查詢分離模式、微服務模式、多級緩存模式。nginx
1. 查詢分離模式數據庫
這種模式主要解決單機數據庫壓力過大,從而致使業務緩慢甚至超時,查詢響應時間變長的問題,也包括須要大量數據庫服務器計算資源的查詢請求。這個能夠說是單庫單應用模式的升級版本,也是技術架構迭代演進過程當中的必經之路。
後端
這種模式的通常設計見下圖:設計模式
如上圖所示,這種模式較單庫單應用模式與內容分發模式多了幾個部分,一個是業務數據庫的主從分離,一個是引入了ES,爲何要這樣?都解決了哪些痛點,下面具體結合業務需求場景進行敘述。瀏覽器
場景一:全文關鍵詞檢索緩存
我想這個需求,絕大多數應用都會有,若是使用傳統的數據庫技術,大部分可能都會使用like這種SQL語句,高級一點多是先分詞,而後經過分詞index相關的記錄。SQL語句的性能問題與全表掃描機制致使了很是嚴重的性能問題,如今基本上不多見到。服務器
這裏的ES是ElasticSearch的縮寫,是一種查詢引擎,相似的還有Solr等,都差很少的技術,ES較Solr配置簡單、使用方便,因此這裏選用了它。另外,ES支持橫向擴展,理論上沒有性能的瓶頸。同時,還支持各類插件、自定義分詞器等,可擴展性較強。在這裏,使用ES不只能夠替代數據庫完成全文檢索功能,還能夠實現諸如分頁、排序、分組、分面等功能。具體的,請同窗們自行學習之。那怎麼使用呢?一個通常的流程是這樣的:微信
服務端把一條業務數據落庫網絡
服務端異步把該條數據發送到ES架構
ES把該條記錄按照規則、配置放入本身的索引庫
客戶端查詢的時候,由服務端把這個請求發送到ES,獲得數據後,根據需求拼裝、組合數據,返回給客戶端
實際中怎麼用,還請同窗們根據實際狀況作組合、取捨。
場景二:大量的普通查詢
這個場景是指咱們的業務中的大部分輔助性的查詢,如:取錢的時候先查詢一下餘額,根據用戶的ID查詢用戶的記錄,取得該用戶最新的一條取錢記錄等。咱們確定是要每天要用的,並且用的還很是多。同時呢,咱們的寫入請求也是很是多的,致使大量的寫入、查詢操做壓向同一數據庫,而後,數據庫掛了,系統掛了,領導生氣了,被開除了,還不起房貸了,露宿街頭了,老婆跟別人跑了,......
不敢想,因此要求咱們必須分散數據庫的壓力,一個業界較成熟的方案就是數據庫的讀寫分離,寫的時候入主庫,讀的時候讀從庫。這樣就把壓力分散到不一樣的數據庫了,若是一個讀庫性能不行,扛不住的話,能夠一主多從,橫向擴展。可謂是一劑良藥啊!那怎麼使用呢?一個通常的流程是這樣的:
服務端把一條業務數據落庫
數據庫同步或異步或半同步把該條數據複製到從庫
服務端讀數據的時候直接去從庫讀相應的數據
比較簡單吧,一些聰明的、愛思考的、上進的同窗可能發現問題了,也包括上面介紹的場景一,就是延遲問題,如:數據尚未到從庫,我就立刻讀,那麼是讀不到的,會發生問題的。
對於這個問題,各家公司解決的思路不同,方法不盡相同。一個廣泛的解決方案是:讀不到就讀主庫,固然這麼說也是有前提條件的,但具體的方案這裏就不一一展開了,我可能會在接下來的分享中詳解各類方案。
另外,關於數據庫的複製模式,還請同窗們自行學習,太多了,這裏說不清。該總結一下這種模式的優缺點的了,以下:
優勢:減小數據庫的壓力,理論上提供無限高的讀性能,間接提升業務(寫)的性能,專用的查詢、索引、全文(分詞)解決方案。
缺點:數據延遲,數據一致性的保證。
2. 微服務模式
上面的模式看似不錯,解決了性能問題,我能夠不用露宿街頭了、老婆仍是個人,哈哈。可是
軟件系統天生的複雜性決定了,除了性能,還有其餘諸如高可用、健壯性等大量問題等待咱們解決,再加上各個部門間的撕逼、扯皮,更讓咱們碼農雪上加霜,因此
繼續吧......
微服務模式能夠說是最近的熱點,花花綠綠、大大小小、國內國外的公司都在鼓吹,實踐這個模式,但是大部分都沒有弄清楚爲何要這麼作,也並不知道這麼作有什麼好處、壞處,在這裏,我將以我本身的親身實踐說一下我對這個模式的見解,不喜勿噴!隨着業務與人員的增長,遇到了以下的問題:
單機數據庫寫請求量大量增長,致使數據庫壓力變大
數據庫一旦掛了,那麼整個業務都掛了
業務代碼愈來愈多,都在一個GIT裏,愈來愈難以維護
代碼腐化嚴重、臭味愈來愈濃
上線愈來愈頻繁,常常是一個小功能的修改,就要整個大項目要從新編譯
部門愈來愈多,該哪一個部門改動大項目中的哪一個東西,撕逼的厲害
其餘一些外圍系統直接鏈接數據庫,致使一旦數據庫結構發生變化,全部的相關係統都要通知,甚至對修改不敏感的系統也要通知
每一個應用服務器須要開通全部的權限、網絡、FTP、各類各樣的,由於每一個服務器部署的應用都是同樣的
做爲架構師,我已經失去了對這個系統的把控......
爲了解決上述問題,我司使用了微服務模式,這種模式的通常設計見下圖:
如上圖所示,我把業務分塊,作了垂直切分,切成一個個獨立的系統,每一個系統各自衍化,有本身的庫、緩存、ES等輔助系統,系統之間的實時交互經過RPC,異步交互經過MQ,經過這種組合,共同完成整個系統功能。
那麼,這麼作是否真的解決上述問題了呢?不玩虛的,一個個來講。對於問題一,因爲拆分紅了多個子系統,系統的壓力被分散了,而各個子系統都有本身的數據庫實例,因此數據庫的壓力變小。
對於問題二,一個子系統A的數據庫掛了,只是影響到系統A和使用系統A的那些功能,不會全部的功能不可用,從而解決一個數據庫掛了,致使全部功能不可用的問題。
問題3、四,也由於拆分獲得了解決,各個子系統有本身獨立的GIT代碼庫,不會相互影響。通用的模塊可經過庫、服務、平臺的形式解決。
問題五,子系統A發生改變,須要上線,那麼我只須要編譯A,而後上線就能夠了,不須要其餘系統作一樣的事情。
問題六,順應了康威定律,我部門該幹什麼事、輸出什麼,也經過服務的形式暴露出來,我部只管把我部的職責、軟件功能作好就能夠。
問題七,全部須要我部數據的需求,都經過接口的形式發佈出去,客戶經過接口獲取數據,從而屏蔽了底層數據庫結構,甚至數據來源,我部只需保證我部的接口契約沒有發生變化便可,新的需求增長新的接口,不會影響老的接口。
問題八,不一樣的子系統須要不一樣的權限,這個問題也優雅的解決了。
問題九,暫時控制住了複雜性,我只需控制好大的方面,定義好系統邊界、接口、大的流程,而後再分而治之、逐個擊破、合縱連橫。
目前來講,全部問題獲得解決!bingo!
可是,還有許多其餘的反作用會隨之產生,如RPC、MQ的超高穩定性、超高性能,網絡延遲,數據一致性等問題,這裏就不展開來說了,太多了,一本書都講不完。
另外,對於這個模式來講,最難把握的是度,切記不要切分過細,我見過一個功能一個子系統,上百個方法分紅上百個子系統的,真的是太過分了。實踐中,一個較爲可行的方法是:能不分就不分,除非有很是必要的理由!。
優勢:相對高性能,可擴展性強,高可用,適合於中等以上規模公司架構。
缺點:複雜、度很差把握。指不只須要一個能在高層把控大方向、大流程、整體技術的人,還須要可以針對各個子系統有針對性的開發。把握很差度或者濫用的話,這個模式拔苗助長!
3.多級緩存模式
這個模式能夠說是應對超高查詢壓力的一種廣泛採用的策略,基本的思想就是在全部鏈路的地方,能加緩存就加緩存,以下圖所示:
如上圖所示,通常在三個地方加入緩存,一個是客戶端處,一個是API網關處,一個是具體的後端業務處,下面分別介紹。
客戶端處緩存:這個地方加緩存能夠說是效果最好的---無延遲。由於不用通過長長的網絡鏈條去後端業務處獲取數據,從而致使加載時間過長,客戶流失等損失。雖然有CDN的支持,可是從客戶端到CDN仍是有網絡延遲的,雖然不大。具體的技術依據不一樣的客戶端而定,對於WEB來說,有瀏覽器本地緩存、Cookie、Storage、緩存策略等技術;對於APP來說,有本地數據庫、本地文件、本地內存、進程內緩存支持。以上提到的各類技術有興趣的同窗能夠繼續展開來學習。若是客戶端緩存沒有命中,那麼就會去後端業務拿數據,通常來說,都會有個API網關,在這裏加緩存也是很是有必要的。
API網關處緩存:這個地方加緩存的好處是不用把請求發送到後方,直接在這裏就處理了,而後返回給請求者。常見的技術,如http請求,API網關用的基本都是nginx,可使用nginx自己的緩存模塊,也可使用Lua+Redis技術定製化。其餘的也都大同小異。
後端業務處:這個我想就不用多說了,你們應該差很少都知道,什麼Redis,Memcache,Jvm內等等,不熬述了。
實踐中,要結合具體的實際狀況,綜合利用各級緩存技術,使得各類請求最大程度的在到達後端業務以前就被解決掉,從而減小後端服務壓力、減小佔用帶寬、加強用戶體驗。至因而否只有這三個地方加緩存,我以爲要活學活用,心法比劍法重要!總結一下這個模式的優缺點:
優勢:抗住大量讀請求,減小後端壓力。
缺點:數據一致性問題較突出,容易發生雪崩,即:若是客戶端緩存失效、API網關緩存失效,那麼全部的大量請求瞬間壓向後端業務系統,後果可想而知。
本次分享的中篇到此結束,接下來的下篇將介紹最後三種模式:分庫分表模式、彈性伸縮模式、多機房模式,相對來說技術含量更高,敬請期待!