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