(給ImportNew加星標,提高Java技能)
本文來源:石杉的架構筆記(ID:shishan100)
前言
現在有很多Java技術方向的同學在找工作的時候,肯定都會去招聘網站上找職位投遞簡歷。
但是在很多職位JD上往往會有這樣的一個要求:熟悉分散式系統理論、設計和開發,具備複雜分散式系統構建經驗。
之前不少同學後臺留言問過我:這個分散式系統的設計和開發經驗,到底指的是什麼?那麼這篇文章就給大家來解釋一下這個問題。
1.從單塊系統說起
要說分散式系統是什麼東西,那麼就得先從單塊系統開始說起。
很多同學應該都知道,如果你在一些中小型的傳統軟體公司裡工作,那麼很有可能現在在做的系統是如下這個樣子。
所有的程式碼都在一個工程裡,最多可能就是透過maven等構件工具拆分了一下程式碼工程模組,不同的模組可以放在不同的工程程式碼裡。
在部署的時候,可能就是直接線上上的幾臺機器裡直接放到裡面的tomcat下來執行。
然後在web伺服器前面可能會有一層負載均衡伺服器,比如用nginx或者是其他的負載均衡裝置。
很多流量很小的企業內部系統,比如OA、CRM、財務等系統,甚至可能就直接在一臺機器的tomcat下部署一下。
然後直接配置一下域名解析,就可以讓這個系統的可能幾十個,或者幾百個使用者透過訪問域名來使用這個軟體了。
至於說系統的依賴大概來說很可能只有一個,那就是MySQL、Oracle等關係型資料庫,可能會在某臺機器上專門部署一個資料庫,讓應用系統來使用。
大家看看下麵的圖,體會一下這種單體架構。
這種系統在很多中小型公司裡現在還是比較多的,就是典型的單塊系統,所有程式碼在一個工程,部署在一個tomcat裡即可,這裡包含了系統所有的功能。
你哪怕就部署一臺機器,這個系統也可以執行,只不過為了所謂的“高可用”,可能一般會部署兩臺機器,前面加一層負載均衡裝置,這樣其中一個機器掛了,另外一個機器上還有一個系統可以用。
2.團隊越來越大,業務越來越複雜
其實上面說的那種單塊系統,如果是一個10人以內的小團隊大家一起維護和開發一個使用者數量不多,請求量不大的系統,也是沒問題的,還挺方便的,對吧。
你搞一個程式碼倉庫,然後就一份程式碼,每個人都在自己本地寫程式碼,最後把程式碼合併一下,做做測試,然後就直接部署基於Tomcat來就可以了。
但是問題就在於說,如果你的團隊超過了10個人,比如有20個人,甚至幾十個人,上百個人要一起協作開發這個系統,然後裡面的業務邏輯特別多,可能功能模組多達幾百個。這個時候就麻煩了,你要是還用那種單塊系統的樣式,那肯定是很痛苦的。
因為幾十個人維護一個單塊系統,大家在一個工程裡寫程式碼,大量的衝突以及程式碼合併都會讓人崩潰。
而且部署的時候會有各種衝突,比如某個功能模組要上線了,但是他必須得把整個單塊系統所有的功能都回歸測試一遍才敢上線。
因為大家的程式碼都在一個工程裡,都是耦合在一起的,你修改了程式碼,必須全部測試一遍才能保證系統正常。
所以說這個時候,就必須想辦法把系統改造成分散式系統了。
3.分散式出現:龐大系統分而治之
這個時候就可以嘗試把一個大的系統拆分為很多小的系統,甚至很多小的服務,然後幾個人組成一個小組就專門維護其中一個小系統,或者每個人維護一個小服務。
簡單來說,就是分而治之,這樣每個人可以專註維護自己的程式碼。
然後不同的小系統自己開發、測試和上線,都不會跟別人耦合在一起,可以自己獨立進行,非常的方便,大大簡化了大規模系統的開發成本。
不同的子系統之間,就是透過介面互相來回呼用,每個子系統都有自己的資料庫,大家看下麵的圖。
4.分散式系統所帶來的技術問題
那麼大家這個時候可以思考一下,如果你的公司是採用這種分散式系統的方式來構建公司的一個大規模系統的,那麼這個時候會涉及到哪些技術問題?
(1)分散式服務框架
你如果要讓不同的子系統或者服務之間互相通訊,首先必須有一套分散式服務框架。
也就是各個服務可以互相感知到對方在哪裡,可以傳送請求過去,可以透過HTTP或者RPC的方式。
在這裡,最常見的技術就是dubbo以及spring cloud,當然大廠一般都是自己有服務框架
(2)分散式事務
一旦你的系統拆分為了多個子系統之後,那麼一個貫穿全域性的分散式事務應該怎麼來實現?
這個你需要瞭解TCC、最終一致性、2PC等分散式事務的實現方案和開源技術。
(3)分散式鎖
不同的系統之間如果需要在全域性加鎖獲取某個資源的鎖定,此時應該怎麼來做?
畢竟大家不是在一個JVM裡了,不可能用synchronized來在多個子系統之間實現鎖吧,是不是?
(4)分散式快取
如果你原來就是個單塊系統,那麼你其實是可以在單個JVM裡進行本地快取就可以了,比如搞一個HashMap來快取一些資料。
但是現在你有很多個子系統,他們如果要共享一個快取,你應該怎麼辦?是不是需要引入Redis等快取系統?
(5)分散式訊息系統
在單塊系統內,就一個JVM行程內部,你可以用類似LinkedList之類的資料結構作為一個本地記憶體裡的佇列。
但是多個子系統之間要進行訊息佇列的傳遞呢?那是不是要引入類似RabbitMQ之類的分散式訊息中介軟體?
(6)分散式搜尋系統
如果在單塊系統內,你可以比如在本地就基於Lucene來開發一個全文檢索模組,但是如果是分散式系統下的很多子系統,你還能直接基於Lucene嗎?
明顯不行,你需要在系統裡引入一個外部的分散式搜尋系統,比如Elasticsearch。
(7)其他很多的技術
比如說分散式配置中心、分散式日誌中心、分散式監控告警中心、分散式會話,等等,都是分散式系統場景下你需要使用和瞭解的一些技術。
因為沿用單塊系統時代的那些技術已經不行了,比如說你單塊系統的時候,直接在本地用一個properties檔案存放自己的配置即可,日誌也寫到本地即可。
但是分散式時代呢?
你那麼多的子系統,怎麼共享同一份配置?怎麼把各個系統的日誌聚合寫到一個地方來檢視?
單塊系統的時候,你一個web應用直接基於Servlet API提供的Session會話功能即可,那麼分散式時代呢,你有N多個子系統如果要共享會話該怎麼做?
5.一句話總結:什麼是分散式系統設計和開發經驗?
其實分析完了之後,大家應該就大概知道了,招聘JD上寫這個分散式系統的設計和開發經驗,其實他是一個很大的主題,裡麵包含很多的內容。
你的系統一旦分散式了之後,通訊、快取、訊息、事務、鎖、配置、日誌、監控、會話,等等各種原來單塊系統場景下很容易解決的問題,都會變得很複雜,需要引入大量外部的技術。
所以你有沒有參與過類似這樣的一個大的分散式系統?你有沒有基於各種技術解決過分散式系統場景下的各種技術問題?這就是人家希望和要求的分散式系統設計和開發的經驗。如果大家還沒接觸過,建議多去學習一下。
6.補充說明:中介軟體系統及大資料系統
最後給大家說明一點,一般這種招聘JD,如果是Java崗位要求分散式相關的經驗,其實主要還是上面說的那些東西,他面向的是分散式的業務系統的構建。
但是其實分散式系統本身是一個非常複雜的話題,因為剛才說的只是一個分散式業務系統要依賴哪些技術來進行構建。
但是其實比如Kafka、Rocket等中介軟體,本身他也是分散式的,你要搞明白他們自己是如何實現分散式的,又是一個非常複雜的話題。
此外,像hadoop、spark、hbase等大資料系統,本身也都是世界上最最複雜的分散式系統,這又涉及到大資料領域的話題了,以後有機會可以單獨聊聊。
作者:中華石杉,十餘年BAT架構經驗傾囊相授。
個人微信公眾號:石杉的架構筆記(ID:shishan100)