1. 程式人生 > >微服務想用好,先把分散式和微服務之間的關係搞清楚

微服務想用好,先把分散式和微服務之間的關係搞清楚

# 一、分散式和微服務架構的定義 分散式應用場景涵蓋的面非常廣,我理解的部分: * 不同程序之間的互相通訊, * 不同主機的分散式物件之間呼叫, * 用於大資料儲存的分散式檔案系統, * 用於網路之間相互識別的命名服務, * 叢集中計算或儲存的無中心對等模型, * 分散式事務, * 資料副本在分散式環境中的複製, * 雲端計算服務, * 音視訊在網路中的點播和傳輸 * .... 微服務架構的目的是對原來過於大而重的雲應用服務進行解耦,手段是進行比較合理的業務模組拆解,拆解的粒度往往由架構師掌握,實現細粒度的服務,服務在雲端形成分散式狀態。 那麼微服務就具有了分散式的一些應用場景,比如:不同主機的分散式物件之間呼叫,以前EJB用RMI(遠端方法呼叫),現在微服務常用RPC(遠端過程呼叫);再比如:用於網路之間相互識別的命名服務,以前EJB是JNDI命名服務,現在SpringCloud的Euraka用於微服務的註冊和發現,也是分散式是命名服務。 如何通俗地理解「分散式系統」,它解決了哪些問題,有什麼優缺點? [理解「分散式系統」曾經發生的事情](https://mp.weixin.qq.com/s/brpLgCKvVhyE2QDcefMivw) 上面是我另外一個回答,裡面比較詳細地描述了歷史上過去EJB和Spring的比較,也是分散式與單體應用的比較。那時候EJB代表分散式服務,而spring代表單體服務。 ![file](https://img2020.cnblogs.com/other/497767/202103/497767-20210308133314327-1518710133.png) 上面的圖簡單的描繪了一種最簡單的單體服務向微服務拆解的過程。當然微服務面臨的挑戰不僅僅這麼簡單,這只是微服務的一種比較初始的狀態。 # 二、分散式和微服務這兩者解決了什麼問題 **分散式是計算、服務、儲存在網路中互相交流與協作的形式和狀態** **分散式到底解決了什麼?** ![file](https://img2020.cnblogs.com/other/497767/202103/497767-20210308133314796-1190800794.png) 上圖就是典型的分散式計算,一個大檔案被切分成四份,MapReduce分成四個任務(程序),然後在同一主機不同程序,或不同主機上進行資料處理,最終再通過網路匯聚到一個合併任務。那麼這個時候到分散式就是任務並行,解決了單任務的效率問題。 ![file](https://img2020.cnblogs.com/other/497767/202103/497767-20210308133315160-1522396990.png) 上圖是個典型的分散式狀態協調管理圖,是Hadoop HDFS叢集的HA高可用架構,主副兩個Namonode節點,必須活著一個,當判斷主的掛了,必須讓副的頂上去,這個時候,三個ZK(zookeeper)組成的叢集就是作為主副節點的協調者,通過ZKFC程序實現對Namoenode節點的心跳監控和切換命令下發。 另外三個Journalnode節點形成的叢集又是namonode分散式狀態資料儲存的地方,當主namonode掛了,所有的狀態必須快速的恢復到副namenode的上面,所以Journalnode必須持續同步狀態,滿足hdfs叢集狀態的快速恢復 那麼分散式中非常關鍵的一個應用場景——叢集,上述的Hadoop hdfs叢集,就需要有一個或幾個角色(zookeeper,Journalnode),作為叢集狀態的協調者和管理者。有時候這種狀態管理是對等的(GlusterFS),有時候這種狀態管理是集中的(Hadoop就是這樣)。 **微服務又解決了什麼問題呢?** 如果這時候在提微服務的分散式優勢,就不是目的,而是手段了。微服務只是藉助了分散式架構,達到了自己的目的。所以微服務不是基礎技術架構的問題,而是上層應用的架構問題。 ![file](https://img2020.cnblogs.com/other/497767/202103/497767-20210308133315410-214198709.png) 上面的例子是個簡單的網際網路醫療服務單體應用,這時候問診、藥品、訂單、即時訊息都是網際網路醫療最核心的業務,資訊推送目的是將網際網路醫療平臺的各類資訊進行網際網路資訊服務平臺的推送、釋出和交流,達到自我推廣的目的。 可恰恰資訊推送服務的更新程度很高,因為需要對外連線的網際網路服務平臺情況複雜,也會有新的服務平臺納入到模組範圍,那麼作為單體應用就存在這樣一個部署問題,每次更新一個新的資訊推送功能,就要整體服務重新部署一次,那麼這種影響對於核心服務就造成了很大的困擾,這時候的患者、醫生、醫院的業務影響都是大規模的。 ![file](https://img2020.cnblogs.com/other/497767/202103/497767-20210308133315694-1912786805.png) 再看看微服務架構,如果將資訊推送服務作為單獨的微服務存在,其他微服務只是將需要推送到網際網路服務平臺的內容進行遠端呼叫即可,甚至用訊息中心的方式,打包成訊息,實現訊息事件驅動,讓對外發布服務的部署不會干預到其他核心服務,使得整體平臺因為部署釋出而造成的影響降到最低。這種方式是不是看起來就舒服多了,非常利於部署、釋出,甚至增強了整體系統的魯棒性。 當然微服務解決的問題還有很多,團隊分工的細粒度、迭代速度的提升、更易於小範圍重構,利於持續化整合(devops)等等,就不一一具體描述了,只把它很有特點的部分拿出來理解一下。 # 三、這些架構帶來的利弊 分散式對應的是就是單機,其優點上節描述了一些,就不贅述了,缺點也很大 部署不簡單,運維不簡單 網路瓶頸和故障會有重要的影響, 節點若失效,就要有察覺和熱替換機制, 一致性問題,例如分散式事務一直是世界性難題, 不僅要考慮均衡負載,更要考慮均衡負載的效果。 資料進行分散式儲存,在有些對等模式下還要考慮資料傾斜問題。 微服務除了分散式儲存缺點6之外,上述前5個缺點基本上都完美的繼承了。 # 四、利用不當所帶來的技術債務 **說說微服務設計不當的麻煩問題吧** (1)微服務解耦後,會將一些業務程式從原來資料庫查詢的方式,轉變成遠端物件呼叫,這個過程我在原來的回答中提過,這是反人性的。形成複雜度和需要約定的介面都帶來了比SQL查詢更大的工作量。而且更反人性的方式就是資料庫也跟著微服務進行分庫,到底哪些資料需要冗餘,哪些資料還能保持資料庫正規化,基本都能把高程們煩死。 (2)經驗欠缺的微服務架構師,容易將微服務切得太細,假如一個單體若被切分成一千個微服務,而且微服務之間用到了遠端物件序列化和反序列化,那麼這就成了死穴!因為一旦一個微服務的實體物件進行了調整,那麼有多少個關聯的微服務被汙染了,就要不斷定位其他微服務的依賴關係並重新發布,這種工作量已經超出了本該解決業務問題的工作量。 因此微服務的劃分一定要注意,而且RPC之間的物件傳遞儘量用簡單、鬆散的結構來做。微服務劃分的程度根據業務不同而粒度不同,有種約定是一個微服務進行大的重構,需要一週的時間,做為微服務粒度標準。 # 五、專案直接使用微服務架構, 是基於對未來的考慮? 微服務架構的考慮,不應該是對未來的考慮,而是對過去單體式應用出現問題後的一種架構重構,從第一節中的圖可以看到其重構過程,在網際網路醫療的例子中微服務的重構進一步趨向於訊息驅動、事件驅動。 從以往實施微服務的經驗教訓中,我總結出來的經驗,如果是新專案的架構師,可以先選擇單體應用,然後根據業務發展一點點迭代重構到微服務上來,即便過程中微服務的架構不那麼純粹,甚至單體應用和微服務很長一段時間共存,也要慎重從新的專案上直接去設計微服務。 因為誰也不是算命先生,能估算到自己業務系統會在哪一天,哪個層面,哪個範圍就一定需要微服務化解耦。只有系統執行快到那個階段了,才能讓架構師更容易做到合理的微服務化決策。當然了,也有人會有疑惑,系統設計成單體,誰還有心思繼續重構微服務,不如直接做成微服務架構多省事,而我想說的是,若無重構之力行,切勿有微服務之念想。 # 六、K8s和Spring Cloud有什麼區別和聯絡? Spring Cloud是貫徹微服務架構的一種具體實現框架,包括了springboot作為微服務的獨立執行容器,Euraka作為微服務的註冊和發現,zuul服務閘道器,其他的沒怎麼用,就不提,其實閘道器我更喜歡用Openresty。 k8s只是容器的一種編排框架,管理者大量的docker容器,但是現在k8s又不整合docker了,暈得很! docker作為微服務的容器,為每一個微服務都提供了單獨的網路、檔案系統、程序管理等基礎設施,這樣每個微服務的狀態、執行日誌可以更好的被監控和管理。另外容器讓部署過程變得簡單,促進了現在流行的devops開發、釋出、部署一體的管理模式,微服務的容器化其實是天生一對。 # 七、結尾 當我們理解清楚分散式下的各種場景是什麼的一種存在形式的時候,當我們理解微服務又是一種什麼分散式場景的時候,我們就更能清楚的去做好微服務的設計決策。 > [前往讀位元組的知乎——瞭解更多關於大資料的知識](https://www.zhihu.com/people/fangshun/answers) > > 公眾號 "讀位元組" 大資料(技術、架構、應用)的深度,專業解讀 > >![file](https://img2020.cnblogs.com/blog/497767/202103/497767-20210302092018925-696738