分布式與微服務,定義,區別,理解
分布式,微服務區別
簡單的說,微服務是架構設計方式,分布式是系統部署方式,兩者概念不同


微服務是啥?
這里不引用書本上的復雜概論了,簡單來說微服務就是很小的服務,小到一個服務只對應一個單一的功能,只做一件事。這個服務可以單獨部署運行,服務之間可以通過RPC來相互交互,每個微服務都是由獨立的小團隊開發,測試,部署,上線,負責它的整個生命周期。
微服務架構又是啥?
在做架構設計的時候,先做邏輯架構,再做物理架構,當你拿到需求后,估算過最大用戶量和並發量后,計算單個應用服務器能否滿足需求,如果用戶量只有幾百人的小應用,單體應用就能搞定,即所有應用部署在一個應用服務器里,如果是很大用戶量,且某些功能會被頻繁訪問,或者某些功能計算量很大,建議將應用拆解為多個子系統,各自負責各自功能,這就是微服務架構

那么分布式又是啥?
分布式服務顧名思義服務是分散部署在不同的機器上的,一個服務可能負責幾個功能,是一種面向SOA架構的,服務之間也是通過rpc來交互或者是webservice來交互的。邏輯架構設計完后就該做物理架構設計,系統應用部署在超過一台服務器或虛擬機上,且各分開部署的部分彼此通過各種通訊協議交互信息,就可算作分布式部署,生產環境下的微服務肯定是分布式部署的,分布式部署的應用不一定是微服務架構的,比如集群部署,它是把相同應用復制到不同服務器上,但是邏輯功能上還是單體應用。
微服務相比分布式服務來說,它的粒度更小,服務之間耦合度更低,由於每個微服務都由獨立的小團隊負責,因此它敏捷性更高,分布式服務最后都會向微服務架構演化,這是一種趨勢, 不過服務微服務化后帶來的挑戰也是顯而易見的,例如服務粒度小,數量大,后期運維將會很難。
到底什么是分布式系統?
分布式系統背景
說分布式系統必須要說集中式系統,集中式系統中整個項目就是一個獨立的應用,整個應用也就是整個項目,所有的東西都在一個應用里面。
如下圖所示


如一個網站就是一個應用,最后是多個增加多台服務器或者多個容器來達到負載均衡的避免單點故障的目的,當然,數據庫是可以分開部署的。
集中式很明顯的優點就是開發測試運維會比較方便,不用為考慮復雜的分布式環境。
集中式很明顯的弊端就是不易擴展,每次更新都必須更新所有的應用。而且,一個有問題意味着所有的應用都有問題。當系統越來越大,集中式將是系統最大的瓶頸。
什么是分布式系統?
分布式系統是由一組通過網絡進行通信、為了完成共同的任務而協調工作的計算機節點組成的系統。分布式系統的出現是為了用廉價的、普通的機器完成單個計算機無法完成的計算、存儲任務。其目的是利用更多的機器,處理更多的數據。
首先需要明確的是,只有當單個節點的處理能力無法滿足日益增長的計算、存儲任務的時候,且硬件的提升(加內存、加磁盤、使用更好的CPU)高昂到得不償失的時候,應用程序也不能進一步優化的時候,我們才需要考慮分布式系統。因為,分布式系統要解決的問題本身就是和單機系統一樣的,而由於分布式系統多節點、通過網絡通信的拓撲結構,會引入很多單機系統沒有的問題,為了解決這些問題又會引入更多的機制、協議,帶來更多的問題。。。
在很多文章中,主要講分布式系統分為分布式計算(computation)與分布式存儲(storage)。計算與存儲是相輔相成的,計算需要數據,要么來自實時數據(流數據),要么來自存儲的數據;而計算的結果也是需要存儲的。在操作系統中,對計算與存儲有非常詳盡的討論,分布式系統只不過將這些理論推廣到多個節點罷了。
那么分布式系統怎么將任務分發到這些計算機節點呢,很簡單的思想,分而治之,即分片(partition)。對於計算,那么就是對計算任務進行切換,每個節點算一些,最終匯總就行了,這就是MapReduce的思想;對於存儲,更好理解一下,每個節點存一部分數據就行了。當數據規模變大的時候,Partition是唯一的選擇,同時也會帶來一些好處:
(1)提升性能和並發,操作被分發到不同的分片,相互獨立
(2)提升系統的可用性,即使部分分片不能用,其他分片不會受到影響
理想的情況下,有分片就行了,但事實的情況卻不大理想。原因在於,分布式系統中有大量的節點,且通過網絡通信。單個節點的故障(進程crash、斷電、磁盤損壞)是個小概率事件,但整個系統的故障率會隨節點的增加而指數級增加,網絡通信也可能出現斷網、高延遲的情況。在這種一定會出現的“異常”情況下,分布式系統還是需要繼續穩定的對外提供服務,即需要較強的容錯性。最簡單的辦法,就是冗余或者復制集(Replication),即多個節點負責同一個任務,最為常見的就是分布式存儲中,多個節點復雜存儲同一份數據,以此增強可用性與可靠性。同時,Replication也會帶來性能的提升,比如數據的locality可以減少用戶的等待時間。
下面這種來自
Distributed systems for fun and profit 的圖形象生動說明了Partition與Replication是如何協作的。
Partition和Replication是解決分布式系統問題的一記組合拳,很多具體的問題都可以用這個思路去解決。但這並不是銀彈,往往是為了解決一個問題,會引入更多的問題,比如為了可用性與可靠性保證,引用了冗余(復制集)。有了冗余,各個副本間的一致性問題就變得很頭疼,一致性在系統的角度和用戶的角度又有不同的等級划分。如果要保證強一致性,那么會影響可用性與性能,在一些應用(比如電商、搜索)是難以接受的。如果是最終一致性,那么就需要處理數據沖突的情況。CAP、FLP這些理論告訴我們,在分布式系統中,沒有最佳的選擇,都是需要權衡,做出最合適的選擇。
分布式系統挑戰
分布式系統需要大量機器協作,面臨諸多的挑戰:
第一,異構的機器與網絡:
分布式系統中的機器,配置不一樣,其上運行的服務也可能由不同的語言、架構實現,因此處理能力也不一樣;節點間通過網絡連接,而不同網絡運營商提供的網絡的帶寬、延時、丟包率又不一樣。怎么保證大家齊頭並進,共同完成目標,這四個不小的挑戰。
第二,普遍的節點故障:
雖然單個節點的故障概率較低,但節點數目達到一定規模,出故障的概率就變高了。分布式系統需要保證故障發生的時候,系統仍然是可用的,這就需要監控節點的狀態,在節點故障的情況下將該節點負責的計算、存儲任務轉移到其他節點
第三,不可靠的網絡:
節點間通過網絡通信,而網絡是不可靠的。可能的網絡問題包括:網絡分割、延時、丟包、亂序。
相比單機過程調用,網絡通信最讓人頭疼的是超時:節點A向節點B發出請求,在約定的時間內沒有收到節點B的響應,那么B是否處理了請求,這個是不確定的,這個不確定會帶來諸多問題,最簡單的,是否要重試請求,節點B會不會多次處理同一個請求。
總而言之,分布式的挑戰來自不確定性,不確定計算機什么時候crash、斷電,不確定磁盤什么時候損壞,不確定每次網絡通信要延遲多久,也不確定通信對端是否處理了發送的消息。而分布式的規模放大了這個不確定性,不確定性是令人討厭的,所以有諸多的分布式理論、協議來保證在這種不確定性的情況下,系統還能繼續正常工作。
而且,很多在實際系統中出現的問題,來源於設計時的盲目樂觀,覺得這個、那個應該不會出問題。
Fallacies_of_distributed_computing很有意思,介紹了分布式系統新手可能的錯誤的假設:
分布式系統特性與衡量標准
透明性:使用分布式系統的用戶並不關心系統是怎么實現的,也不關心讀到的數據來自哪個節點,對用戶而言,分布式系統的最高境界是用戶根本感知不到這是一個分布式系統,在《
Distributed Systems Principles and Paradigms》一書中,作者是這么說的:
A distributed system is a collection of independent computers that appears to its users as a single coherent system.
可擴展性:分布式系統的根本目標就是為了處理單個計算機無法處理的任務,當任務增加的時候,分布式系統的處理能力需要隨之增加。簡單來說,要比較方便的通過增加機器來應對數據量的增長,同時,當任務規模縮減的時候,可以撤掉一些多余的機器,達到動態伸縮的效果
可用性與可靠性:一般來說,分布式系統是需要長時間甚至7*24小時提供服務的。可用性是指系統在各種情況對外提供服務的能力,簡單來說,可以通過不可用時間與正常服務時間的必知來衡量;而可靠性而是指計算結果正確、存儲的數據不丟失。
高性能:不管是單機還是分布式系統,大家都非常關注性能。不同的系統對性能的衡量指標是不同的,最常見的:高並發,單位時間內處理的任務越多越好;低延遲:每個任務的平均時間越少越好。這個其實跟操作系統CPU的調度策略很像
一致性:分布式系統為了提高可用性可靠性,一般會引入冗余(復制集)。那么如何保證這些節點上的狀態一致,這就是分布式系統不得不面對的一致性問題。一致性有很多等級,一致性越強,對用戶越友好,但會制約系統的可用性;一致性等級越低,用戶就需要兼容數據不一致的情況,但系統的可用性、並發性很高很多。
組件、理論、協議
假設這是一個對外提供服務的大型分布式系統,用戶連接到系統,做一些操作,產生一些需要存儲的數據,那么在這個過程中,會遇到哪些組件、理論與協議呢
用一個請求串起來
用戶使用Web、APP、SDK,通過HTTP、TCP連接到系統。在分布式系統中,為了高並發、高可用,一般都是多個節點提供相同的服務。那么,第一個問題就是具體選擇哪個節點來提供服務,這個就是負載均衡(load balance)。負載均衡的思想很簡單,但使用非常廣泛,在分布式系統、大型網站的方方面面都有使用,或者說,只要涉及到多個節點提供同質的服務,就需要負載均衡。
通過負載均衡找到一個節點,接下來就是真正處理用戶的請求,請求有可能簡單,也有可能很復雜。簡單的請求,比如讀取數據,那么很可能是有緩存的,即分布式緩存,如果緩存沒有命中,那么需要去數據庫拉取數據。對於復雜的請求,可能會調用到系統中其他的服務。
承上,假設服務A需要調用服務B的服務,首先兩個節點需要通信,網絡通信都是建立在TCP/IP協議的基礎上,但是,每個應用都手寫socket是一件冗雜、低效的事情,因此需要應用層的封裝,因此有了HTTP、FTP等各種應用層協議。當系統愈加復雜,提供大量的http接口也是一件困難的事情。因此,有了更進一步的抽象,那就是RPC(remote produce call),是的遠程調用就跟本地過程調用一樣方便,屏蔽了網絡通信等諸多細節,增加新的接口也更加方便。
一個請求可能包含諸多操作,即在服務A上做一些操作,然后在服務B上做另一些操作。比如簡化版的網絡購物,在訂單服務上發貨,在賬戶服務上扣款。這兩個操作需要保證原子性,要么都成功,要么都不操作。這就涉及到分布式事務的問題,分布式事務是從應用層面保證一致性:某種守恆關系。
上面說道一個請求包含多個操作,其實就是涉及到多個服務,分布式系統中有大量的服務,每個服務又是多個節點組成。那么一個服務怎么找到另一個服務(的某個節點呢)?通信是需要地址的,怎么獲取這個地址,最簡單的辦法就是配置文件寫死,或者寫入到數據庫,但這些方法在節點數據巨大、節點動態增刪的時候都不大方便,這個時候就需要服務注冊與發現:提供服務的節點向一個協調中心注冊自己的地址,使用服務的節點去協調中心拉取地址。
從上可以看見,協調中心提供了中心化的服務:以一組節點提供類似單點的服務,使用非常廣泛,比如命令服務、分布式鎖。協調中心最出名的就是chubby,zookeeper。
回到用戶請求這個點,請求操作會產生一些數據、日志,通常為信息,其他一些系統可能會對這些消息感興趣,比如個性化推薦、監控等,這里就抽象出了兩個概念,消息的生產者與消費者。那么生產者怎么講消息發送給消費者呢,RPC並不是一個很好的選擇,因為RPC肯定得指定消息發給誰,但實際的情況是生產者並不清楚、也不關心誰會消費這個消息,這個時候消息隊列就出馬了。簡單來說,生產者只用往消息隊列里面發就行了,隊列會將消息按主題(topic)分發給關注這個主題的消費者。消息隊列起到了異步處理、應用解耦的作用。
上面提到,用戶操作會產生一些數據,這些數據忠實記錄了用戶的操作習慣、喜好,是各行各業最寶貴的財富。比如各種推薦、廣告投放、自動識別。這就催生了分布式計算平台,比如Hadoop,Storm等,用來處理這些海量的數據。
最后,用戶的操作完成之后,用戶的數據需要持久化,但數據量很大,大到按個節點無法存儲,那么這個時候就需要分布式存儲:將數據進行划分放在不同的節點上,同時,為了防止數據的丟失,每一份數據會保存多分。傳統的關系型數據庫是單點存儲,為了在應用層透明的情況下分庫分表,會引用額外的代理層。而對於NoSql,一般天然支持分布式。
一個簡化的架構圖
下面用一個不大精確的架構圖,盡量還原分布式系統的組成部分(不過只能體現出技術,不好體現出理論)

概念與實現
那么對於上面的各種技術與理論,業界有哪些實現呢,下面進行簡單羅列。
當然,下面的這些實現,小部分我用過,知其所以然;大部分聽說過,知其然;還有一部分之前聞所未聞,分類也不一定正確,只是從其他文章抄過來的。羅列在這里,以便日后或深或淺的學習。
-
負載均衡:
Nginx:高性能、高並發的web服務器;功能包括負載均衡、反向代理、靜態內容緩存、訪問控制;工作在應用層
LVS: Linux virtual server,基於集群技術和Linux操作系統實現一個高性能、高可用的服務器;工作在網絡層
-
webserver:
Java:Tomcat,Apache,Jboss
Python:gunicorn、uwsgi、twisted、webpy、tornado
-
service:
SOA、微服務、spring boot,django
-
容器:
docker,kubernetes
-
cache:
memcache、redis等
-
協調中心:
zookeeper、etcd等
zookeeper使用了Paxos協議Paxos是強一致性,高可用的去中心化分布式。zookeeper的使用場景非常廣泛,之后細講。
-
rpc框架:
grpc、dubbo、brpc
dubbo是阿里開源的Java語言開發的高性能RPC框架,在阿里系的諸多架構中,都使用了dubbo + spring boot
-
消息隊列:
kafka、rabbitMQ、rocketMQ、QSP
消息隊列的應用場景:異步處理、應用解耦、流量削鋒和消息通訊
-
實時數據平台:
storm、akka
-
離線數據平台:
hadoop、spark
PS: apark、akka、kafka都是scala語言寫的,看到這個語言還是很牛逼的
-
dbproxy:
cobar也是阿里開源的,在阿里系中使用也非常廣泛,是關系型數據庫的sharding + replica 代理
-
db:
mysql、oracle、MongoDB、HBase
-
搜索:
elasticsearch、solr
-
日志:
rsyslog、elk、flume
分布式系統是若干獨立計算機的集合,這計算機對用戶來說就像單個相關系統。
以上定義摘自<<分布式系統原理與范型>>一書。
也就是說分布式系統背后是由一系列的計算機組成的,但用戶感知不到背后的邏輯,就像訪問單個計算機一樣。
說的有點繞,我們可以來簡單看下分布式系統圖。


分布式系統利弊
在分布式系統中:
1、應用可以按業務類型拆分成多個應用,再按結構分成接口層、服務層;我們也可以按訪問入口分,如移動端、PC端等定義不同的接口應用;
2、數據庫可以按業務類型拆分成多個實例,還可以對單表進行分庫分表;
3、增加分布式緩存、搜索、文件、消息隊列、非關系型數據庫等中間件;
很明顯,分布式系統可以解決集中式不便擴展的弊端,我們可以很方便的在任何一個環節擴展應用,就算一個應用出現問題也不會影響到別的應用。
隨着微服務Spring Cloud & Docker的大熱,及國內開源分布式Dubbo框架的重生,分布式技術發展非常迅速。
分布式系統雖好,也帶來了系統的復雜性,如分布式事務、分布式鎖、分布式session、數據一致性等都是現在分布式系統中需要解決的難題,雖然已經有很多成熟的方案,但都不完美。分布式系統也增加了開發測試運維成本,工作量增加,分布式系統管理不好反而會變成一種負擔。
分布式與集群的區別是什么?
鎮貼神圖

下面就正經解釋下三種結構的區別吧~
列子: 去飯店吃飯就是一個完整的業務,飯店的廚師、配菜師、傳菜員、服務員就是分布式;廚師、配菜師、傳菜員和服務員都不止一個人,這就是集群;分布式就是微服務的一種表現形式,分布式是部署層面,微服務是設計層面。
單機結構
我想大家最最最熟悉的就是單機結構,一個系統業務量很小的時候所有的代碼都放在一個項目中就好了,然后這個項目部署在一台服務器上就好了。整個項目所有的服務都由這台服務器提供。這就是單機結構。
那么,單機結構有啥缺點呢?我想缺點是顯而易見的,單機的處理能力畢竟是有限的,當你的業務增長到一定程度的時候,單機的硬件資源將無法滿足你的業務需求。此時便出現了集群模式,往下接着看。
集群結構
列子: 集群就是假如有十個要你一個人一天做完,你一天最多做五 六個做不完 所以你老板就再招了一個人 你們二個人就可以一天做完了
集群模式在程序猿界有各種裝逼解釋,有的讓你根本無法理解,其實就是一個很簡單的玩意兒,且聽我一一道來。
單機處理到達瓶頸的時候,你就把單機復制幾份,這樣就構成了一個“集群”。集群中每台服務器就叫做這個集群的一個“節點”,所有節點構成了一個集群。每個節點都提供相同的服務,那么這樣系統的處理能力就相當於提升了好幾倍(有幾個節點就相當於提升了這么多倍)。
但問題是用戶的請求究竟由哪個節點來處理呢?最好能夠讓此時此刻負載較小的節點來處理,這樣使得每個節點的壓力都比較平均。要實現這個功能,就需要在所有節點之前增加一個“調度者”的角色,用戶的所有請求都先交給它,然后它根據當前所有節點的負載情況,決定將這個請求交給哪個節點處理。這個“調度者”有個牛逼了名字——負載均衡服務器。
集群結構的好處就是系統擴展非常容易。如果隨着你們系統業務的發展,當前的系統又支撐不住了,那么給這個集群再增加節點就行了。但是,當你的業務發展到一定程度的時候,你會發現一個問題——無論怎么增加節點,貌似整個集群性能的提升效果並不明顯了。這時候,你就需要使用微服務結構了。
分布式結構
先來對前面的知識點做個總結。
從單機結構到集群結構,你的代碼基本無需要作任何修改,你要做的僅僅是多部署幾台服務器,每台服務器上運行相同的代碼就行了。但是,當你要從集群結構演進到微服務結構的時候,之前的那套代碼就需要發生較大的改動了。所以對於新系統我們建議,系統設計之初就采用微服務架構,這樣后期運維的成本更低。但如果一套老系統需要升級成微服務結構的話,那就得對代碼大動干戈了。所以,對於老系統而言,究竟是繼續保持集群模式,還是升級成微服務架構,這需要你們的架構師深思熟慮、權衡投入產出比。
OK,下面開始介紹所謂的分布式結構。
分布式結構就是將一個完整的系統,按照業務功能,拆分成一個個獨立的子系統,在分布式結構中,每個子系統就被稱為“服務”。這些子系統能夠獨立運行在web容器中,它們之間通過RPC方式通信。
舉個例子,假設需要開發一個在線商城。按照微服務的思想,我們需要按照功能模塊拆分成多個獨立的服務,如:用戶服務、產品服務、訂單服務、后台管理服務、數據分析服務等等。這一個個服務都是一個個獨立的項目,可以獨立運行。如果服務之間有依賴關系,那么通過RPC方式調用。
這樣的好處有很多:
-
系統之間的耦合度大大降低,可以獨立開發、獨立部署、獨立測試,系統與系統之間的邊界非常明確,排錯也變得相當容易,開發效率大大提升。
-
系統之間的耦合度降低,從而系統更易於擴展。我們可以針對性地擴展某些服務。假設這個商城要搞一次大促,下單量可能會大大提升,因此我們可以針對性地提升訂單系統、產品系統的節點數量,而對於后台管理系統、數據分析系統而言,節點數量維持原有水平即可。
-
服務的復用性更高。比如,當我們將用戶系統作為單獨的服務后,該公司所有的產品都可以使用該系統作為用戶系統,無需重復開發。
概念:
集群是個物理形態,分布式是個工作方式。
分布式:一個業務分拆多個子業務,部署在不同的服務器上
集群:同一個業務,部署在多個服務器上
1:分布式是指將不同的業務分布在不同的地方。而集群指的是將幾台服務器集中在一起,實現同一業務。
分布式中的每一個節點,都可以做集群。而集群並不一定就是分布式的。
舉例:就比如新浪網,訪問的人多了,他可以做一個群集,前面放一個響應服務器,后面幾台服務器完成同一業務,如果有業務訪問的時候,響應服務器看哪台服務器的負載不是很重,就將給哪一台去完成。
而分布式,從窄意上理解,也跟集群差不多,但是它的組織比較松散,不像集群,有一個組織性,一台服務器垮了,其它的服務器可以頂上來。
分布式的每一個節點,都完成不同的業務,一個節點垮了,那這個業務就不可訪問了。
2:簡單說,分布式是以縮短單個任務的執行時間來提升效率的,而集群則是通過提高單位時間內執行的任務數來提升效率。
例如:如果一個任務由 10 個子任務組成,每個子任務單獨執行需 1 小時,則在一台服務器上執行該任務需 10 小時。
采用分布式方案,提供 10 台服務器,每台服務器只負責處理一個子任務,不考慮子任務間的依賴關系,執行完這個任務只需一個小時。(這種工作模式的一個典型代表就是 Hadoop 的 Map/Reduce 分布式計算模型)
而采用集群方案,同樣提供 10 台服務器,每台服務器都能獨立處理這個任務。假設有 10 個任務同時到達,10 個服務器將同時工作,1 小時后,10 個任務同時完成,這樣,整身來看,還是 1 小時內完成一個任務!
好的設計應該是分布式和集群的結合,先分布式再集群,具體實現就是業務拆分成很多子業務,然后針對每個子業務進行集群部署,這樣每個子業務如果出了問題,整個系統完全不會受影響。
另外,還有一個概念和分布式比較相似,那就是微服務。
微服務是一種架構風格,一個大型復雜軟件應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是松耦合的。每個微服務僅關注於完成一件任務並很好地完成該任務。在所有情況下,每個任務代表着一個小的業務能力。
區別:
1.分布式

將一個大的系統划分為多個業務模塊,業務模塊分別部署到不同的機器上,各個業務模塊之間通過接口進行數據交互。區別分布式的方式是根據不同機器不同業務。
上面:service A、B、C、D 分別是業務組件,通過API Geteway進行業務訪問。
注:分布式需要做好事務管理。
分布式事務可參考:
微服務架構的分布式事務解決方案
2.集群模式

集群模式是不同服務器部署同一套服務對外訪問,實現服務的負載均衡。區別集群的方式是根據部署多台服務器業務是否相同。
注:集群模式需要做好session共享,確保在不同服務器切換的過程中不會因為沒有獲取到session而中止退出服務。
一般配置Nginx*的負載容器實現:靜態資源緩存、Session共享可以附帶實現,Nginx支持5000個並發量。
3.分布式是否屬於微服務?
答案是肯定的。
微服務的意思也就是將模塊拆分成一個獨立的服務單元通過接口來實現數據的交互。
4.微服務架構
微服務的設計是為了不因為某個模塊的升級和BUG影響現有的系統業務。微服務與分布式的細微差別是,微服務的應用不一定是分散在多個服務器上,他也可以是同一個服務器。

分布式和微服的
架構很相似,只是部署的方式不一樣而已。
https://www.yinxiang.com/everhub/note/1f39cf3a-4799-4d60-9f65-38f4042aad8c