JAVA總結--dubbo與zookeeper


讀累了就看看實操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: 服務運行容器。

調用關系說明:

  1. 服務容器負責啟動,加載,運行服務提供者。

  2. 服務提供者在啟動時,向注冊中心注冊自己提供的服務。

  3. 服務消費者在啟動時,向注冊中心訂閱自己所需的服務。

  4. 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者。

  5. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。

  6. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鍾發送一次統計數據到監控中心。

    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有如下特征:

  1. 監視(Watch)

    客戶端可以在Znode上面增加監視事件,當Znode發生變化的時候,ZooKeeper就會觸發watch,並向客戶端發送且僅通知一次,watch只能被觸發一次。

  2. 數據訪問

    節點數據訪問是原子性,每個節點都有ACL(權限列表),規定了用戶的權限,可以划分權限設定。

  3. 節點類型

    節點類型分為兩種,永久性和臨時性。臨時性節點在每次會話結束的時候,自動刪除。也可以手動刪除臨時節點,而且臨時節點沒法建立子節點。

  4. 順序節點

    每個節點創建的時候,都會給新創建的節點增加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,保證子節點創建的時序性,從而也形成了每個客戶端的全局時序。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM