JAVA總結--dubbo與zookeeper

讀累了就看看實操http://www.javashuo.com/article/p-ugnyhqlq-s.html html

1、SOA前端

概念:SOA:Service-Oriented Architecture,面向服務的架構,將應用程序的不一樣功能(服務)經過定義的接口來實現數據通訊;服務治理;服務調度中心和治理中心;node

架構演變:單一應用架構ORM  |  垂直應用架構MVC  |  分佈式服務架構RPC  |  流動計算架構SOA算法

ORM :流量小,單一應用,部署一塊兒;關注於簡化增刪改查的對象關係映射,spring

MVC :流量增長,應用拆分;關注於提升前端開發速度;服務器

RPC :遠程過程調用;經過網絡進行遠程計算機服務的請求;核心業務抽取;關注於業務的複用和整合;網絡

由統一到分佈式:架構

使用場景由混亂到統一:負載均衡

 SOA又叫服務治理,SOA就是幫助咱們把服務之間調用的亂七八糟的關係給治理起來,而後提供一個統一的標準;框架

統一標準:各系統的協議、地址、交互方式。

新的交互方式:各個系統分別根據統一標準向數據總線進行註冊,各子系統調用其餘子系統時,咱們並不關心若是找到其餘子系統,咱們只招數據總線,數據總線再根據統一標準找其餘子系統,因此數據總線在這裏充當一個只路人的做用。

數據總線是起到調度服務的做用,數據總線不是集成服務,數據總線更新一個調度框架,每一個服務須要根據約定向數據總線註冊服務;服務不是通過總線的,是直接向client響應;

 2、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轉爲客戶端須要的接口

 3、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,保證子節點建立的時序性,從而也造成了每一個客戶端的全局時序。

相關文章
相關標籤/搜索