讀累了就看看實操https://www.cnblogs.com/huasky/p/10214642.html
一、SOA
概念:SOA:Service-Oriented Architecture,面向服務的架構,將應用程序的不同功能(服務)通過定義的接口來實現數據通信;服務治理;服務調度中心和治理中心;
架構演變:單一應用架構ORM | 垂直應用架構MVC | 分布式服務架構RPC | 流動計算架構SOA
ORM :流量小,單一應用,部署一起;關注於簡化增刪改查的對象關系映射,
MVC :流量增加,應用拆分;關注於提高前端開發速度;
RPC :遠程過程調用;通過網絡進行遠程計算機服務的請求;核心業務抽取;關注於業務的復用和整合;
由統一到分布式:
使用場景由混亂到統一:
SOA又叫服務治理,SOA就是幫助我們把服務之間調用的亂七八糟的關系給治理起來,然后提供一個統一的標准;
統一標准:各系統的協議、地址、交互方式。
新的交互方式:各個系統分別根據統一標准向數據總線進行注冊,各子系統調用其他子系統時,我們並不關心如果找到其他子系統,我們只招數據總線,數據總線再根據統一標准找其他子系統,所以數據總線在這里充當一個只路人的作用。
數據總線是起到調度服務的作用,數據總線不是集成服務,數據總線更新一個調度框架,每個服務需要根據約定向數據總線注冊服務;服務不是經過總線的,是直接向client響應;
二、dubbo
概念:dubbo:一個解決大規模服務治理的高性能分布式服務框架;分布式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,是阿里巴巴SOA服務化治理方案的核心框架;
流程與說明:
dubbo的架構圖如下:
其中,
· Provider: 暴露服務的服務提供方。
· Consumer: 調用遠程服務的服務消費方。
· Registry: 服務注冊與發現的注冊中心。
· Monitor: 統計服務的調用次調和調用時間的監控中心。
· Container: 服務運行容器。
調用關系說明:
-
服務容器負責啟動,加載,運行服務提供者。
-
服務提供者在啟動時,向注冊中心注冊自己提供的服務。
-
服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
-
注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者。
-
服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
-
服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鍾發送一次統計數據到監控中心。
Dubbo提供了很多協議,Dubbo協議、RMI協議、Hessian協議,Dubbo源代碼有各種協議的實現,我們之前沒用Dubbo之前時,大部分都用Hessian來使用我們服務的暴露和調用,利用HessianProxyFactory調用遠程接口。
原理:
初始化過程細節:
第一步,就是將服務裝載容器中,然后准備注冊服務。和spring中啟動過程類似,spring啟動時,將bean裝載進容器中的時候,首先要解析bean。所以dubbo也是先讀配置文件解析服務。
解析服務:
1)、基於dubbo.jar內的Meta-inf/spring.handlers配置,spring在遇到dubbo名稱空間時,會回調DubboNamespaceHandler類。
2)、所有的dubbo標簽,都統一用DubboBeanDefinitionParser進行解析,基於一對一屬性映射,將XML標簽解析為Bean對象。生產者或者消費者初始化的時候,會將Bean對象轉會為url格式,將所有Bean屬性轉成url的參數。 然后將URL傳給Protocol擴展點,基於擴展點的Adaptive機制,根據URL的協議頭,進行不同協議的服務暴露和引用。
暴露服務:
a、 直接暴露服務端口
在沒有使用注冊中心的情況,這種情況一般適用在開發環境下,服務的調用這和提供在同一個IP上,只需要打開服務的端口即可。 即,當配置 or ServiceConfig解析出的URL的格式為: Dubbo://service-host/com.xxx.TxxService?version=1.0.0 基於擴展點的Adaptiver機制,通過URL的“dubbo://”協議頭識別,直接調用DubboProtocol的export()方法,打開服務端口。
b、向注冊中心暴露服務:
和上一種的區別:需要將服務的IP和端口一同暴露給注冊中心。 ServiceConfig解析出的url格式為: registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode(“dubbo://service-host/com.xxx.TxxService?version=1.0.0”)
基於擴展點的Adaptive機制,通過URL的“registry://”協議頭識別,調用RegistryProtocol的export方法,將export參數中的提供者URL先注冊到注冊中心,再重新傳給Protocol擴展點進行暴露: Dubbo://service-host/com.xxx.TxxService?version=1.0.0
引用服務:
a、直接引用服務:
在沒有注冊中心的,直連提供者情況下, ReferenceConfig解析出的URL格式為: Dubbo://service-host/com.xxx.TxxService?version=1.0.0
基於擴展點的Adaptive機制,通過url的“dubbo://”協議頭識別,直接調用DubboProtocol的refer方法,返回提供者引用。
b、從注冊中心發現引用服務:
此時,ReferenceConfig解析出的URL的格式為: registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode(“consumer://consumer-host/com.foo.FooService?version=1.0.0”)
基於擴展點的Apaptive機制,通過URL的“registry://”協議頭識別,就會調用RegistryProtocol的refer方法,基於refer參數總的條件,查詢提供者URL,如: Dubbo://service-host/com.xxx.TxxService?version=1.0.0
基於擴展點的Adaptive機制,通過提供者URL的“dubbo://”協議頭識別,就會調用DubboProtocol的refer()方法,得到提供者引用。 然后RegistryProtocol將多個提供者引用,通過Cluster擴展點,偽裝成單個提供這引用返回。
暴露服務的主過程:
首先ServiceConfig類拿到對外提供服務的實際類ref,然后將ProxyFactory類的getInvoker方法使用ref生成一個AbstractProxyInvoker實例,到這一步就完成具體服務到invoker的轉化。接下來就是Invoker轉換到Exporter的過程。 Dubbo處理服務暴露的關鍵就在Invoker轉換到Exporter的過程,下面我們以Dubbo和rmi這兩種典型協議的實現來進行說明: Dubbo的實現: Dubbo協議的Invoker轉為Exporter發生在DubboProtocol類的export方法,它主要是打開socket偵聽服務,並接收客戶端發來的各種請求,通訊細節由dubbo自己實現。 Rmi的實現: RMI協議的Invoker轉為Exporter發生在RmiProtocol類的export方法,他通過Spring或Dubbo或JDK來實現服務,通訊細節由JDK底層來實現。
服務消費的主過程:
首先ReferenceConfig類的init方法調用Protocol的refer方法生成Invoker實例。接下來把Invoker轉為客戶端需要的接口
三、zookeeper(可作為Dubbo的注冊中心使用)
概念zookeeper:為分布式應用程序提供協調服務;為其他分布式程序提供協調服務;本身也是分布式程序;
zookeeper提供的服務:配置維護、域名服務、分布式同步、組服務;其實只提供了兩個功能(管理數據和監聽數據): 管理(存儲,讀取)用戶程序提交的數據; 並為用戶程序提供數據節點監聽服務;
應用場景:
Zookeeper主要是做注冊中心用;基於Dubbo框架開發的提供者、消費者都向Zookeeper注冊自己的URL,消費者還能拿到並訂閱提供者的注冊URL,以便在后續程序的執行中去調用提供者。而提供者發生了變動,也會通過Zookeeper向訂閱的消費者發送通知;
用於擔任服務生產者和服務消費者的注冊中心,服務生產者將自己提供的服務注冊到Zookeeper中心,服務的消費者在進行服務調用的時候先到Zookeeper中查找服務,獲取到服務生產者的詳細信息之后,再去調用服務生產者的內容與數據;
zookeeper數據模型
Znode:目錄結構;節點;
數據模型是一棵樹(ZNode Tree),由斜杠(/)進行分割的路徑,就是一個ZNode,如/hbase/master,其中hbase和master都是ZNode;
每個Znode節點都包含了該節點的數據、狀態信息、子節點。狀態信息用來記錄每次節點變更后的時間戳、版本等信息。因此,當版本發生變更的時候,ZooKeeper會同步修改該節點的狀態信息。
Znode有如下特征:
-
監視(Watch)
客戶端可以在Znode上面增加監視事件,當Znode發生變化的時候,ZooKeeper就會觸發watch,並向客戶端發送且僅通知一次,watch只能被觸發一次。
-
數據訪問
節點數據訪問是原子性,每個節點都有ACL(權限列表),規定了用戶的權限,可以划分權限設定。
-
節點類型
節點類型分為兩種,永久性和臨時性。臨時性節點在每次會話結束的時候,自動刪除。也可以手動刪除臨時節點,而且臨時節點沒法建立子節點。
-
順序節點
每個節點創建的時候,都會給新創建的節點增加1個身份數字,從1開始。它的格式“%10d”,計數超過2^32-1時,會有溢出風險。
Znode類型有4種:永久性節點、臨時性節點、永久性有序節點、臨時性有序節點
ZooKeeper采用ACL(Access Control Lists)策略來進行權限控制;
zookeeper的5種權限:
·CREATE: 創建子節點的權限。
·READ: 獲取節點數據和子節點列表的權限。
·WRITE:更新節點數據的權限。
·DELETE: 刪除子節點的權限。
·ADMIN: 設置節點ACL的權限。
注意:CREATE 和 DELETE 都是針對子節點的權限控制。
zookeeper原理:
(1)ZooKeeper分為服務器端(Server) 和客戶端(Client),客戶端可以連接到整個 ZooKeeper服務的任意服務器上(除非 leaderServes 參數被顯式設置, leader 不允許接受客戶端連接)。
(2)客戶端使用並維護一個 TCP 連接,通過這個連接發送請求、接受響應、獲取觀察的事件以及發送心跳。如果這個 TCP 連接中斷,客戶端將自動嘗試連接到另外的 ZooKeeper服務器。客戶端第一次連接到 ZooKeeper服務時,接受這個連接的 ZooKeeper服務器會為這個客戶端建立一個會話。當這個客戶端連接到另外的服務器時,這個會話會被新的服務器重新建立。
(3)上圖中每一個Server代表一個安裝Zookeeper服務的機器,即是整個提供Zookeeper服務的集群(或者是由偽集群組成);
(4)組成ZooKeeper服務的服務器必須彼此了解。 它們維護一個內存中的狀態圖像,以及持久存儲中的事務日志和快照, 只要大多數服務器可用,ZooKeeper服務就可用;
(5)ZooKeeper 啟動時,將從實例中選舉一個 leader,Leader 負責處理數據更新等操作,一個更新操作成功的標志是當且僅當大多數Server在內存中成功修改數據。每個Server 在內存中存儲了一份數據。
(6)Zookeeper是可以集群復制的,集群間通過Zab協議(Zookeeper Atomic Broadcast)來保持數據的一致性;
(7)Zab協議包含兩個階段:leader election階段和Atomic Brodcast階段。
-
a) 集群中將選舉出一個leader,其他的機器則稱為follower,所有的寫操作都被傳送給leader,並通過brodcast將所有的更新告訴給follower。
-
b) 當leader崩潰或者leader失去大多數的follower時,需要重新選舉出一個新的leader,讓所有的服務器都恢復到一個正確的狀態。
-
c) 當leader被選舉出來,且大多數服務器完成了 和leader的狀態同步后,leadder election 的過程就結束了,就將會進入到Atomic brodcast的過程。
-
d) Atomic Brodcast同步leader和follower之間的信息,保證leader和follower具有形同的系統狀態。\
Leader算法:以Fast Paxos算法為基礎的
zookeeper角色:Leader、learner或follower、ObServer
領導者(Leader):負責進行投票的發起和決議,更新系統狀態;
學習者(Learner)或跟隨者(Follower):接收客戶端請求,並向客戶端返回結果,在選主過程中參與投票;如果接收到的客戶端請求為寫請求,將轉發給Leader來完成系統狀態的更新;
觀察者(ObServer):接收客戶端的連接,將寫請求轉發給Leader;不參與選主過程的投票,僅同步Leader狀態;擴展系統,提高讀寫速度;
應用場景
1 統一命名服務(如Dubbo服務注冊中心)
Dubbo是一個分布式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,是阿里巴巴SOA服務化治理方案的核心框架,每天為2,000+個服務提供3,000,000,000+次訪問量支持,並被廣泛應用於阿里巴巴集團的各成員站點。
在Dubbo實現中:
服務提供者在啟動的時候,向ZK上的指定節點/dubbo/${serviceName}/providers目錄下寫入自己的URL地址,這個操作就完成了服務的發布。
服務消費者啟動的時候,訂閱/dubbo/${serviceName}/providers目錄下的提供者URL地址, 並向/dubbo/${serviceName} /consumers目錄下寫入自己的URL地址。
注意,所有向ZK上注冊的地址都是臨時節點,這樣就能夠保證服務提供者和消費者能夠自動感應資源的變化。 另外,Dubbo還有針對服務粒度的監控,方法是訂閱/dubbo/${serviceName}目錄下所有提供者和消費者的信息。
2 配置管理 (如淘寶開源配置管理框架Diamond)
在大型的分布式系統中,為了服務海量的請求,同一個應用常常需要多個實例。如果存在配置更新的需求,常常需要逐台更新,給運維增加了很大的負擔同時帶來一定的風險(配置會存在不一致的窗口期,或者個別節點忘記更新)。zookeeper可以用來做集中的配置管理,存儲在zookeeper雞群中的配置,如果發生變更會主動推送到連接配置中心的應用節點,實現一處更新處處更新的效果。
3 分布式集群管理 (Hadoop分布式集群管理)
這通常用於那種對集群中機器狀態,機器在線率有較高要求的場景,能夠快速對集群中機器變化作出響應。這樣的場景中,往往有一個監控系統,實時檢測集群機器是否存活。過去的做法通常是:監控系統通過某種手段(比如ping)定時檢測每個機器,或者每個機器自己定時向監控系統匯報“我還活着”。 這種做法可行,但是存在兩個比較明顯的問題:
(1) 集群中機器有變動的時候,牽連修改的東西比較多。
(2) 有一定的延時。
利用ZooKeeper有兩個特性,就可以實現另一種集群機器存活性監控系統:
(1) 客戶端在節點 x 上注冊一個Watcher,那么如果 x?的子節點變化了,會通知該客戶端。
(2) 創建EPHEMERAL類型的節點,一旦客戶端和服務器的會話結束或過期,那么該節點就會消失。
例如,監控系統在 /clusterServers 節點上注冊一個Watcher,以后每動態加機器,那么就往 /clusterServers 下創建一個 EPHEMERAL類型的節點:/clusterServers/{hostname}. 這樣,監控系統就能夠實時知道機器的增減情況,至於后續處理就是監控系統的業務了。
4 分布式鎖(強一致性)
這個主要得益於ZooKeeper為我們保證了數據的強一致性。鎖服務可以分為兩類,一個是 保持獨占,另一個是 控制時序。
(1) 所謂保持獨占,就是所有試圖來獲取這個鎖的客戶端,最終只有一個可以成功獲得這把鎖。通常的做法是把zk上的一個znode看作是一把鎖,通過create znode的方式來實現。所有客戶端都去創建 /distribute_lock 節點,最終成功創建的那個客戶端也即擁有了這把鎖。
(2) 控制時序,就是所有視圖來獲取這個鎖的客戶端,最終都是會被安排執行,只是有個全局時序了。做法和上面基本類似,只是這里 /distribute_lock 已經預先存在,客戶端在它下面創建臨時有序節點(這個可以通過節點的屬性控制:CreateMode.EPHEMERAL_SEQUENTIAL來指定)。Zk的父節點(/distribute_lock)維持一份sequence,保證子節點創建的時序性,從而也形成了每個客戶端的全局時序。