引言
隨著越來越多的人參與到互聯網的浪潮來,曾經的單體應用架構越來越無法滿足需求,所以,分布式集群架構出現,也因此,分布式搭建開發成為了Web開發者必掌握的技能之一。
那什么是分布式呢?怎么實現分布式以及怎么處理分布式帶來的問題呢?本系列文章就來源于對分布式各組件系統的學習總結。
包含但不限于Zookeeper、Dubbo、消息隊列(ActiveMQ、Kafka、RabbitMQ)、Nosql(redis、MongoDB)、Niginx、分庫分表MyCat、Netty等內容。
一、什么是分布式
簡單的說,“分工協作,專人做專事”就是分布式的概念。
就好比你是你們公司唯一的碼農,那么前后端都需要你自己來開發(單體架構),但隨著業務的增長,你確實忙不過來了,老板給你招來了一個前端,那么你就只需要專注后端開發就行了(分布式)。
但是軟件的分布式搭建遠遠不像現實例子中這么簡單,需要考慮和處理很多方面的問題,我們先了解以下幾個常見的概念:
- 集群:你們公司業務增長的非常快,老板發現你一個后端忙不過來了,就又招了幾個后端開發來協助你,這就是后端集群;再往后,發現前端也忙不過來了,又配備幾個前端,就是前端集群。所以也不難看出,將應用拆分后,你可以有針對性地擴展單個服務,做成集群,這就是分布式的好處之一。
- 節點:這個也非常好理解,一個服務就是一個節點,比如你就是后端集群中的一個節點,而集群本身也可以看成是整個應用的一個集群節點。
- 副本:副本就是為服務和數據提供的冗余,保證高可用。
- 中間件:為開發者提供便利,屏蔽復雜的底層的一類框架組件。如服務管理通信、序列化、負載均衡等組件。
上圖就是一個簡單的分布式架構,但并不是所有的應用一開始就要設計為分布式架構。
因為一開始業務量并不大,沒有必要耗費大量的時間和成本去完成一個分布式架構,甚至有可能到最后都用不上,因此在設計時我們應該遵循演進原則,由簡入深。
下面就來簡單分析一下分布式架構的演進過程。
二、分布式架構的演化過程
單機版
以商城為例,為了簡單說明,這里就只列出用戶、訂單、配送服務。
如圖,大部分應用最開始都是將應用和數據庫放到一臺物理機上提供服務,但隨著訪問量的提升,服務器負載越來越高。
我們首先會優化代碼、對機器做垂直擴容(內存、容量)等,但單臺機器的性能是存在上限的,且對單機擴容的性價比會隨著性能的提升越來越低,那我們就會想到增加服務器。
將應用服務器和數據庫服務器分離
在一開始,我們可能只會增加一臺服務器,并將應用和數據庫分離:
搭建應用服務器集群
隨著訪問量的繼續增加,單臺應用服務器也無法滿足需求了,我們就需要搭建應用服務器集群來對外提供服務了
但是,在搭建應用服務器集群之后,問題就出現了,用戶在訪問時,應該到哪個服務器上去?
如何平均服務器壓力?以及用戶的session如何維護(A首先訪問了1號應用服務器并登陸,但下次請求可能是去到2號服務器,但這臺服務器上并沒有用戶的session信息)?
我們可以在用戶層和應用層之間加上一個負載均衡器來平衡服務器的負載,session可以采取同步的方式,或者增加單獨的session共享服務器。
數據庫讀寫分離
應用層的問題暫時解決了,但是此時數據庫又頂不住了。那該如何做呢?
只是簡單的增加數據庫的服務器來提供存儲和訪問能力么?那肯定不行,這樣數據就不一致了。
所以我們需要將數據庫分為讀庫和寫庫。查詢請求都到讀庫去,而寫入請求都到寫庫去。
但這樣也存在幾個問題:
- 數據如何同步以及同步延遲如何處理?
- 應用層數據源的選擇
- 大數據查詢搜索,可以引入搜索引擎
- 避免每次訪問直接到達數據庫,可以引入redis等緩存數據庫緩存熱點數據
問題看似都解決了,但是每個數據庫都存儲的是同樣的數據,隨著業務繼續擴大, 我們就不得不考慮對數據庫做水平或垂直拆分:
- 水平拆分:將同一個表中的數據拆分至多個數據庫中
- 垂直拆分:將不同業務的數據放到不同的數據庫中
應用拆分
業務繼續增長,數據庫達到瓶頸時可以繼續增加服務器解決,但是應用層呢?也只是單純的增加服務器么?
基于二八原則,其實大部分訪問量是集中在20%的功能上的,如果我們只是單純的增加服務器,那么無疑會浪費掉許多的資源,所以我們會想到能不能針對這20%的應用做擴展呢?
當然是可以的,只不過我們需要先將應用拆分為多個子系統(一般是根據業務):
隨著應用拆分隨之而來的問題是,公用的代碼如何處理?各服務之間如何通信?
公用代碼我們不可能放到每個服務中去,而是應該提出來對外提供服務,同時服務之間的調用可以通過RPC或者HTTP方式來實現。
演化至此,這樣的架構就是一個成熟的分布式架構了。
但是,架構還是會隨著業務和技術的提升不停地演化;而此時你有沒有發現這樣的一個架構和馮諾伊曼結構很像呢!
輸入輸出設備對應用戶和服務之間的輸入輸出,數據庫服務器就像是存儲設備,而整個應用層就像是一個CPU(控制器、運算器)。
所以,分布式架構可以簡單的理解為將多臺計算機組成的一臺超級計算機。
三、分布式架構的設計
在設計分布式架構時,我們需要了解幾個基本的概念。
- 主流架構模型-SOA和微服務
- CAP和BASE理論
- DDD(領域驅動設計)
這些理論限于篇幅原因,這里就不展開詳述,讀者可自行查閱。下面主要來談談分布式架構的高可用設計。
分布式架構的高可用設計
在分布式架構中,常常面臨的兩個矛盾的問題是一致性和高可用,這兩個是無法同時滿足的,那我們舍誰取誰呢?
從用戶的角度分析,我們寧可獲取到舊數據,也不愿意等半天都打不開應用,所以常常是保證高可用,讓數據達到最終一致性,那么如何設計高可用的分布式架構呢?主要從以下幾個方面:
- 搭建服務集群,提高負載,避免單點故障。尤其是特別重要的服務,如訪問量較高的服務和核心服務(一旦掛掉就會導致整個應用不可用的服務)。
- 應對災難,搭建異地災備,預防地區因發生地震、臺風等自然災害導致地區的集群服務器都不可用。
- 接口限流以及服務降級。為防止過高的并發量造成服務器負載過高而出現故障,應對接口限流,同時,當某個或多個服務出現故障時,應當服務降級,避免拖累整個應用。比如支付時因網絡故障等導致無法支付,但搜索商品和下單仍然可用。
- 故障監控報警。
- 服務的可伸縮性,易于水平擴張服務器數量。
- 使用緩存降低數據庫壓力。
- 使用CDN等加速靜態資源的訪問。
高可用的分布式架構需要考慮非常多的方面,針對不同的場景有不同的解決方案,而對于不同的公司而言也不需要一應俱全,需要在實踐中多思考總結,根據自己的業務情況來設計。
總結
本文從理論層面講述了分布式的基本概念、演化過程,以及設計,從宏觀角度搞清楚分布式的起源以及分布式帶來的一系列問題,也就能明白各項技術出現的原因以及應用的場景。
作者:夜勿語 來源:https://blog.csdn.net/l6108003/article/details/94835586