1、單體架構:
這是我們最初的一個系統架構:無論我們是什么樣的一個客戶端,UI呈現是一個什么樣的,后端都只有一個,相對比較簡單;
以前項目就一個進程,各種模塊項目都放在一起,隨着業務的發展,數據量,流量的不斷增長,單體不夠用了,【eg:一個石頭太大,搬不動】那我們怎么做呢?
- 要么換大力士【升級硬件】:but:升級硬件也是有上限的;
- 要么多個人來搬,常見的2種方式有:
- 垂直拆分
- 水平
那什么是垂直呢?什么是水平呢?
A:垂直:也就是系統拆分,按系統業務、邏輯拆分成多個合作完成。
一個人搞不完的事,按系統業務拆分,一個人干一部分,把事情干完;
但是:垂直也有一定的局限性,拆分多了,就比較碎片化,不僅不利用管理,單一節點壓力還是會很大;
B:水平:也就是我們平時說的集群負載均衡
以前這個邏輯一個實例處理的,現在換成多個實例,干相同的事,換成多個實例,請求來了該找誰呢?這時候我們就用到了負載均衡,搭載Nginx做轉發處理
一個人搞不定,那我們都多來幾個干相同的事,請求來了,分發一下,把所有的事干了
擴展:Nginx-->高性能的Http和反向代理web服務器;工作原理:作為反向代理,請求之后,配置策略,根據策略把請求轉發出去;
事實上,它們做的事都是一樣的,都是都是想辦法用有限的服務器,計算資源來處理原始的請求,以應對滿足高並發,大數據的一些訴求;
現在有3個服務實例,它們都要寫log,那么我們不可能每個都寫,這樣就會重復構建,共同的東西,就可以把它抽出來,服務共享,也就是代碼復用
假如一個項目有100個功能點,按照2:8原則來分配,只有20%的業務是常用的,它們會承擔80%的流量,而80%是一個進程,那個點的資源是所有程序共享的,就會划不來,那我們把20%的高頻服務拆分出來,服務共享,獨立的部分增加計算資源,多分一些資源,其它少一點,這樣才能資源最大化利用;
2、分布式
如果在項目架構之間,多個項目,把一些操作,邏輯,業務或者服務獨立出來,當作服務來共享調用,一次請求就變為:我調用A,A調用logserver,那么這樣下來我們就來了一個新的名詞,叫:分布式
分布式:多進程協助完成業務;
A:分布式的代價:
那么分布式有那么好么?eg:有一個詞叫“欲戴皇冠,必成其重”,eg:分布式鎖,分布式事務,以及它的復雜性..........;
分布式鎖:一個東西,最多一個人處理,2個人同時操作就會出問題,那么我們就要做一些進程上的互斥;
分布式事務:你操作成功了,我操作失敗了,所以我們就要來做些操作。來保證數據的一致性;
為什么那么麻煩,我們還要使用它?好處:獨立運維,獨立擴展,獨立部署【享受自己單獨的硬件資源】,更好的利用資源;
3.微服務架構(Microsercice Architecture)
隨着時間的推移,業務倒逼技術不斷的發展,分布式的問題都解決了,那么分布式就變成了常規手段,推演下午就變成了微服務;
A.定義:
微服務架構就是一個用分布式服務拆分業務邏輯,完成解耦的架構模式(架構風格)。
B:究竟怎么拆分微服務?
eg:三層架構里面有一層,DLL業務邏輯層----UI負責調用
微服務---業務邏輯都放在服務里面---UI客戶端負責調用,該集群集群,該部署部署,該運維運維,該注冊發現,該網關網關,各種東西佩奇,就變成了微服務
那么真如我們描述的這么簡單么?
以前我們調用BLL,在一個進程里,成功或者失敗,結果一目了然,清清楚楚,那么我們變為了微服務,調用服務慢,或者失敗,原因可能是代碼,網絡丟包,抖動,服務器,數據庫掛了,超時等一系列可能性問題
從單進程變為分布式,一切都不一樣了
3.微服務架構全組件解析
把方法都拆成獨立服務了,怎么樣保證項目是可用的呢?
1.保證服務的高可用;
2.服務的可伸縮性;
A.核心基礎:高可用
問題:風險太大--串行結構,任意節點出問題,全流程奔潰,這是項目的高壓線,如果一個服務的可用性是99%,那2個,3個...7個,8個呢?簡直不敢想象后果,充分體現了可用性的重要性
那我們怎么去保證可用性:答案是集群【可以理解為找備胎?】
Nginx+KeepAlived做IP漂移,我們用nginx作反向代理負載均衡,通過nginx將客戶端請求用輪詢方式發送給服務器,我們部署了的一個nginx掛了怎么辦 ?那我們就部署兩個,使用keepalived監控nginx的健康狀態,當nginx出現宕機時自動主備切換,實現IP漂移,來實現高可用
B.伸縮性:
總有服務是應對多個客戶端的,我們的系統也會在不同的時段,出現壓力不均的情況,甚至突然間壓力變大10,100倍就會導致我們系統的奔潰,那問題來了,怎么辦呢?我們總不可能在事先准備100份冗余資源吧。
我們的預期目標是希望它能自動伸縮,隨着壓力情況,自動開啟新節點或者關閉節點。(Docker+swarm,或者K8S)
游離在外面,請求過不去,怎么納入集群里面管理起來使用?
Nginx其自身的屬性:可以自動減少,減少時會自動重啟Nginx,如果新增節點則不能實現自動擴張,修改配置重啟Nginx服務那現在怎么辦?
1.注冊發現
那如果新增一個呢?
節點刪除
如果滿足了這個特性,就做到了自動伸縮,ConSul就完成了,我們的架構也就演變為:
GRPC:局域網內部傳輸具有更高的性能,外部我們還是使用.core webapi
問題:
1.服務暴露:這么多服務實例可見,這么多端口暴露在外面還是會很危險;
2.負載均衡;
3.調用服務的麻煩;
新增一個網關,通過包一層的方式去解決上面的問題,由網關GeteWay去處理,做的事跟Nginx差不多;
它們的區別:Nginx是一個單獨的服務器,要擴展需要寫Lua腳本,但網關還要很多額外功能;
2.網關Gateway
網關用Ocelot,Kong,推薦用Ocelot,[c#寫的方便擴展,微軟出品]
從圖中可以看出網關是一切網絡的出入口,這樣顯得它在整個架構中尤為重要,那我們就要考慮到它的可用性,一個掛了,整個流程都結束了,那我們就集群唄;
集群完,這么多網關怎么訪問,難道我記4個地址嗎?去調用哪一個呢?
問題:網關調用服務實例,還是要擔心服務掛了,服務超時的問題,所以這個地方網關除了去做服務注冊,轉發,還要去做路由映射,,,,,
沒有網關的請求:
加了網關的請求:
有了網關,就可以把關系整理清晰
請求超時:
雪崩:在串行化鏈路里面,任意節點的故障都會導致整個鏈路的崩潰。那怎么處理這個問題呢?:
限時解決:定義1S的請求,>1s,不管你是否成功,我都不會再管這個結果,認為Fail,雖然這中間有一個失敗了,但是保證了整個鏈路的健康狀態
限流:
熔斷,降級等等
最后除了以上這些,還有鑒權,授權
加了鑒權授權,請求的時候,帶上Token,有權限就請求,沒權限只能出門左轉回家
到這,核心模型就搭建完成了
問題思考:那么我們如何拆分才能保證系統高內聚,低耦合?