目錄:
一你踩、什么是分布式系統(tǒng)诅岩?
二、為什么要走分布式系統(tǒng)架構带膜?
三吩谦、系統(tǒng)如何進行拆分?
四膝藕、分布式之后帶來的技術挑戰(zhàn)式廷?
一、什么是分布式系統(tǒng)芭挽?
在談分布式系統(tǒng)架構前滑废,我們先來看看蝗肪,什么是分布式系統(tǒng)?
假設原來我們有一個系統(tǒng)策严,代碼量30多萬行∷肽剑現在拆分成20個小系統(tǒng),每個小系統(tǒng)1萬多行代碼妻导。
原本代碼之間都是直接基于Spring框架走JVM內存調用逛绵,現在拆開來,將20個小系統(tǒng)部署在不同的機器上倔韭,然后基于分布式服務框架(比如dubbo)搞一個rpc調用术浪,接口與接口之間通過網絡通信來進行請求和響應。
所以分布式系統(tǒng)很重要的特點就是服務間要跨網絡進行調用寿酌,我們來看下面的圖:
此外胰苏,分布式系統(tǒng)可以大概可以分成兩類。
1. 底層的分布式系統(tǒng)醇疼。
比如hadoop hdfs(分布式存儲系統(tǒng))硕并、spark(分布式計算系統(tǒng))、storm(分布式流式計算系統(tǒng))秧荆、elasticsearch(分布式搜索系統(tǒng))倔毙、kafka(分布式發(fā)布訂閱消息系統(tǒng))等。
2. 分布式業(yè)務系統(tǒng)
分布式業(yè)務系統(tǒng)乙濒,把原來用java開發(fā)的一個大塊系統(tǒng)陕赃,給拆分成多個子系統(tǒng),多個子系統(tǒng)之間互相調用颁股,形成一個大系統(tǒng)的整體么库。
舉個例子,假設原來你做了一個OA系統(tǒng)甘有,里面包含了權限模塊诉儒、員工模塊、請假模塊亏掀、財務模塊允睹,一個工程,里面包含了一堆模塊幌氮,模塊與模塊之間會互相去調用,1臺機器部署胁澳。
現在如果你把他這個系統(tǒng)給拆開该互,權限系統(tǒng),員工系統(tǒng)韭畸,請假系統(tǒng)宇智,財務系統(tǒng)蔓搞,4個系統(tǒng),4個工程随橘,分別在4臺機器上部署喂分。
然后一個請求過來,完成這個請求机蔗,員工系統(tǒng)去調用權限系統(tǒng)蒲祈,調用請假系統(tǒng),調用財務系統(tǒng)萝嘁,4個系統(tǒng)分別完成了一部分的事情梆掸。
最后4個系統(tǒng)都干完了以后,才認為是這個請求已經完成了牙言。這就是所謂的分布式業(yè)務系統(tǒng)酸钦。
同樣,我們來一張圖咱枉,感受一下上述過程:
二卑硫、為什么要走分布式系統(tǒng)架構?
有的人可能有疑惑了蚕断,我一臺服務器跑的好好的欢伏,所有系統(tǒng)一個工程全部搞定,多好基括。為啥一定要去搞什么分布式系統(tǒng)架構颜懊,互相調用還要走遠程,似乎還增加了不少工作量风皿?
這里我就以我曾經待過的一個公司的血淚經歷為例河爹,來聊聊這個問題。
很多年前桐款,在沒有走分布式架構的時候咸这,我待的這家公司的各個業(yè)務線都是垂直的 “煙囪式” 項目。
隨著互聯網的快速發(fā)展魔眨,公司的業(yè)務也在不斷的發(fā)展媳维,注冊用戶增加、網站應用的功能遏暴、規(guī)模不斷擴大侄刽,特別是移動互聯網的發(fā)展,APP朋凉、微信州丹、自助終端機等訪問渠道的增加,各種新業(yè)務,新需求不斷涌入墓毒,系統(tǒng)遇到了各種各樣的問題吓揪。
首先是項目工程無節(jié)制的變得臃腫龐大,系統(tǒng)復雜度增加所计,大幾十萬行代碼柠辞,幾十個開發(fā)人員,service層主胧,dao層代碼大量被copy使用叭首,經常各種代碼合并沖突問題要處理,非常耗費時間讥裤。經常是我改動了我的代碼放棒,別人調用了我的接口,導致他的代碼也經常出現問題己英,需要重新測試间螟,麻煩的要死。
然后每次發(fā)布都是幾十萬行代碼的系統(tǒng)一起發(fā)布损肛,大家得一起提心吊膽準備上線厢破,幾十萬行代碼的上線,每次上線都要做很多的檢查治拿,很多異常問題的處理摩泪,每個人都高度緊張,被搞得幾乎崩潰劫谅。
而且如果我現在有個新業(yè)務见坑,打算把相關依賴升級一下,比如升級到最新的spring版本捏检,還不行荞驴,因為這可能導致別人的代碼報錯,不敢隨意亂改技術贯城。并且一個web工程每次啟動都需要好分鐘的時間熊楼,本地IDE里面調試一次代碼都很痛苦。
其次能犯,隨著用戶訪問流量的增加鲫骗,系統(tǒng)負載壓力變大,變得不堪重負踩晶,通過增加實例數执泰,增加硬件擴容能夠帶來的效果已微乎其微,故障頻發(fā)渡蜻,效率低下坦胶。系統(tǒng)質量也越來越難以保證,測試周期也變得越來越長,無法滿足公司業(yè)務發(fā)展的需要顿苇。
以上就是以前待過的公司一些 “不堪回首” 的往事,總得來說税弃,問題主要體現在以下幾個方面:
應用代碼耦合嚴重纪岁,功能擴展難
新需求開發(fā)交互周期長,測試工作量大
新加入的開發(fā)同事需要很長時間才能熟悉系統(tǒng)
升級維護也很困難(改動任何一點地方都要升級整個系統(tǒng))
系統(tǒng)性能提升艱難则果,可用性低幔翰,不穩(wěn)定。
好西壮,既然我們已經深刻體會到了系統(tǒng)耦合的痛苦遗增,那么現在就來看看,系統(tǒng)拆分后帶來的好處:
?首先款青,系統(tǒng)拆分了以后做修,會感覺整個世界都清爽了。幾十萬行代碼的系統(tǒng)抡草,假設拆分成20個服務饰及,平均每個服務就1-3萬行代碼,每個服務部署到單獨的機器上康震。20個工程燎含,就用20個git倉庫代碼,20個開發(fā)人員腿短,每個人維護自己的那個服務就可以了屏箍。
因為是自己獨立的代碼,跟別人沒關系橘忱。再也沒有代碼沖突了赴魁,爽!
每次就測試我自己的代碼就可以了鹦付,爽尚粘!
每次就發(fā)布我自己的一個小服務就可以了,爽敲长!
技術上想怎么升級就怎么升級郎嫁,保持接口定義不變,輸入輸出內容不變就可以了祈噪,爽泽铛!
總結起來一句話,分布式系統(tǒng)拆分之后辑鲤,可以大幅度提升復雜系統(tǒng)大型團隊的開發(fā)效率盔腔。
三、系統(tǒng)如何進行拆分?
一般來說弛随,將系統(tǒng)進行拆分瓢喉,首先需要對系統(tǒng)整體比較熟悉∫ㄍ福可以走多輪拆分的思路栓票,第一次拆分就是將以前的各個大的模塊粗粒度的拆分開來。
比如一個電商系統(tǒng)可以拆分成訂單系統(tǒng)愕够、商品系統(tǒng)走贪、店鋪系統(tǒng)、會員系統(tǒng)惑芭、促銷系統(tǒng)坠狡、支付系統(tǒng)等等。 后面可能每個系統(tǒng)又變得越來越復雜了遂跟,比如說訂單系統(tǒng)又可以進一步拆分出來購物車系統(tǒng)逃沿,庫存系統(tǒng),價格系統(tǒng)等漩勤。
總得來說就是基于領域驅動設計的思想以及實戰(zhàn)經驗總結感挥,同時參考業(yè)界一些常規(guī)做法,大家討論著來進行拆分越败,逐步優(yōu)化触幼,多輪拆分,小步快跑究飞,最終達到一個比較好的狀態(tài)置谦。
四、分布式之后帶來的技術挑戰(zhàn)亿傅?
首先就是分布式服務框架的選用媒峡,目前國內來講主流的還是dubbo與spring cloud。
?我們來思考一下葵擎,使用服務框架主要用來解決什么問題呢谅阿?如果不用dubbo或者spring cloud是否可以做分布式架構呢?不用dubbo或者spring cloud等服務框架當然也是可以的酬滤,但是這就需要自己處理很多事情了签餐。比如,各個子系統(tǒng)走restful接口調用盯串,那么就是http調用氯檐,這時比如傳送過去一個對象,就要自己搞成一個json体捏,然后一次調用失敗后重試怎么做冠摄?
另外糯崎,一般來說都是集群部署,目標系統(tǒng)有多個實例河泳,那么自己還要寫一個負載均衡算法沃呢,如何每次隨機從多個目標機器中挑選一個來調用?
還有拆挥,如果目標系統(tǒng)擴容新部署了一個實例樟插,或者服務器故障下線了一個實例,如何動態(tài)讓調用方感知到呢竿刁? 諸如此類的很多問題,如果不用服務框架的話搪缨,自己這么瞎搞食拜,會遇到各種各樣的問題。
上述過程副编,用一張圖給大家呈現一下:
如果選用了某一個分布式服務框架负甸,就需要深入的掌握這個框架的使用與底層原理,比如 dubbo 就需要搞明白以下的一些問題:
dubbo的工作原理痹届?
dubbo支持的序列化協(xié)議呻待?
dubbo的負載均衡和高可用策略?動態(tài)代理策略队腐?
dubbo的SPI思想蚕捉?
如何基于dubbo進行服務治理、服務降級柴淘、失敗重試以及超時重試迫淹?
dubbo服務接口的冪等性如何設計(比如不能重復扣款,不能重復生成訂單为严,不能重復創(chuàng)建卡號)敛熬?
dubbo服務接口請求的順序性如何保證?
如何自己設計一個類似dubbo的rpc框架第股?
使用spring cloud也是一樣应民,比如eureka的工作原理?feign聲明式調用的原理夕吻?等等各種底層原理要搞懂诲锹。
還有其它一些走分布式架構后常見的要解決的技術問題:
分布式會話
分布式鎖
分布式事務
分布式搜索
分布式緩存
分布式消息隊列
統(tǒng)一配置中心
分布式存儲,數據庫分庫分表
限流梭冠、熔斷辕狰、降級等。
以上這些問題控漠,往深了說蔓倍,每一個點都需要可能 N 篇文章來詳細闡述悬钳,這里沒法逐一展開。