1. 程式人生 > >zookeeper-watcher非同步呼叫子服務

zookeeper-watcher非同步呼叫子服務

zookeeper=檔案系統+通知機制

一、 檔案系統

Zookeeper維護一個類似檔案系統的資料結構:

每個子目錄項如 NameService 都被稱作為 znode,和檔案系統一樣,我們能夠自由的增加、刪除znode,在一個znode下增加、刪除子znode,唯一的不同在於znode是可以儲存資料的。

有四種類型的znode:

1)PERSISTENT-持久目錄節點

客戶端與zookeeper斷開連線後,該節點依舊存在

2) PERSISTENT_SEQUENTIAL-持久順序節點

客戶端與zookeeper斷開連線後,該節點依舊存在,只是Zookeeper給該節點名稱進行順序編號

3)EPHEMERAL-臨時目錄節點

客戶端與zookeeper斷開連線後,該節點被刪除

4)EPHEMERAL_SEQUENTIAL-臨時順序編號目錄節點

客戶端與zookeeper斷開連線後,該節點被刪除,只是Zookeeper給該節點名稱進行順序編號

二、 通知機制

客戶端註冊監聽它關心的目錄節點,當目錄節點發生變化(資料改變、被刪除、子目錄節點增加刪除)時,zookeeper會通知客戶端。

我們可以自定義Watcher,如果是Boolean型變數,當為true時,則使用系統預設的Watcher,系統預設的Watcher是在Zookeeper的建構函式中定義的Watcher。引數中Watcher為空或者false,表示不啟用Wather。

1、一次性觸發器

客戶端在Znode設定了Watch時,如果Znode內容發生改變,那麼客戶端就會獲得Watch事件。例如:客戶端設定getData("/znode1", true)後,如果/znode1發生改變或者刪除,那麼客戶端就會得到一個/znode1的Watch事件,但是/znode1再次發生變化,那客戶端是無法收到Watch事件的,除非客戶端設定了新的Watch。

2、傳送至客戶端

Watch事件是非同步傳送到Client。Zookeeper可以保證客戶端傳送過去的更新順序是有序的。例如:某個Znode沒有設定watcher,那麼客戶端對這個Znode設定Watcher傳送到叢集之前,該客戶端是感知不到該Znode任何的改變情況的。換個角度來解釋:由於Watch有一次性觸發的特點,所以在伺服器端沒有Watcher的情況下,Znode的任何變更就不會通知到客戶端。不過,即使某個Znode設定了Watcher,且在Znode有變化的情況下通知到了客戶端,但是在客戶端接收到這個變化事件,但是還沒有再次設定Watcher之前,如果其他客戶端對該Znode做了修改,這種情況下,Znode第二次的變化客戶端是無法收到通知的。這可能是由於網路延遲或者是其他因素導致,所以我們使用Zookeeper不能期望能夠監控到節點每次的變化。Zookeeper只能保證最終的一致性,而無法保證強一致性。

3、設定watch的資料內容

Znode改變有很多種方式,例如:節點建立,節點刪除,節點改變,子節點改變等等。Zookeeper維護了兩個Watch列表,一個節點資料Watch列表,另一個是子節點Watch列表。getData()和exists()設定資料Watch,getChildren()設定子節點Watch。兩者選其一,可以讓我們根據不同的返回結果選擇不同的Watch方式,getData()和exists()返回節點的內容,getChildren()返回子節點列表。因此,setData()觸發內容Watch,create()觸發當前節點的內容Watch或者是其父節點的子節點Watch。delete()同時觸發父節點的子節點Watch和內容Watch,以及子節點的內容Watch。

Zookeeper Watcher的執行機制

1,Watch是輕量級的,其實就是本地JVM的Callback,伺服器端只是存了是否有設定了Watcher的布林型別。(原始碼見:org.apache.zookeeper.server.FinalRequestProcessor)

2,在服務端,在FinalRequestProcessor處理對應的Znode操作時,會根據客戶端傳遞的watcher變數,新增到對應的ZKDatabase(org.apache.zookeeper.server.ZKDatabase)中進行持久化儲存,同時將自己NIOServerCnxn做為一個Watcher callback,監聽服務端事件變化

3,Leader通過投票通過了某次Znode變化的請求後,然後通知對應的Follower,Follower根據自己記憶體中的zkDataBase資訊,傳送notification資訊給zookeeper客戶端。

4,Zookeeper客戶端接收到notification資訊後,找到對應變化path的watcher列表,挨個進行觸發回撥

watcher分類:

defaultWatcher

existWatcher-->exist()

childWatcher-->getChildren()

dataWatcher-->getData()

watcher原理:

1、建立zookeeper例項的時候接收一個watcher引數,賦值給watchMnanger.defaultWatcher,此watcher與其它watcher不同,主要用於響應與連結狀態轉換有關的事件(建立連結,關閉連結等)

2、ZKWatchManager是客戶端watcher管理器,負責跟蹤多種watcher,每種型別的watcher將會被存在各自的Map中,key為path,value為Set<Watcher>。watcher由ZKWatchManager負責管理,並不會隨請求傳送給server,而只會發給server此請求型別是否註冊了watch

3、在ZKDatabase中,包括一個DataTree,此dataTree持有對nodes以及相關的watcher的資料,server端,WatcherManager是管理client註冊的watcher,其資料結構為HashSet<path,Set<Watcher>>

4、請求到達server之後,在FinalRequestProcessor中,將會處理各種請求,如果檢測到request.getWatch()為true,即請求要求註冊watch,那麼將會把ServerCnxn和path關聯起來,加入到WatherManager相應的列表中.

5、客戶端的請求響應之後,由SendThread.readResponse()處理響應,如果響應code為成功且此請求中註冊了watch,那麼將會把此wath新增到響應的watch列表中。

6、DataTree持有2個WatchManager物件,分別為dataWatches用於管理註冊data操作的watch,childWatches用於管理註冊child操作的watch。

Zookeeper的Watcher機制主要包括客戶端執行緒、客戶端WatchManager和Zookeeper伺服器三部分。在具體的流程上,客戶端向Zookeeper伺服器註冊Watcher事件監聽的同時,會將Watcher物件儲存在 客戶端WatchManager中。當Zookeeper伺服器觸發Watcher事件後,會向客戶端傳送通知,客戶端執行緒從WatchManager中取出對應的Watcher物件執行回撥邏輯(process方法)。

流程:

1、不同子服務在zk上註冊同一個znode節點

2、第一個子服務在節點上建立資料

3、第二個子服務監聽節點的變化

4、當節點改變時做出對應的操作

方法一:watche機制回撥

建立的是持久節點

需要自己將傳遞的引數由json轉化為String

子服務定時呼叫getData方法,判斷是否執行api

一個外部呼叫對應一個監聽

--缺點:每一個介面對應一個定時任務

方法二:zk非同步呼叫api

建立的是臨時節點

可以直接傳遞json

主執行緒需要阻塞等待其他子服務的呼叫api

按create,exits,delete監聽

--每種型別的回撥方法只有一個,需要滿足不同子服務的呼叫

原因

在呼叫一個介面的時候,可能會執行一些不必要的操作,有時這些操作等待響應的時間過長,如果同步呼叫介面,會使當前執行緒阻塞,大大影響了使用者體驗,所以利用zookeeper的watch機制,非同步處理這些操作。

原理

1、Zookeeper提供瞭如下幾種可以"註冊watch"的操作:exist,getChildren,getData;而對於create,setData,delete是有可能觸發"watcher"的操作

2、zookeeper的節點大小為1M

過程

1、建立子服務zookeeper,用於建立節點和對節點進行監聽

2、啟動服務的同時啟動監聽執行緒,建立定時任務讀取zookeeper節點

3、其他子服務執行時呼叫zookeeper服務,建立一個持久時序節點

4、執行緒定時獲取介面對應的子節點,根據子節點中的引數執行相應介面

5、讀取資料之後刪除節點

問題

1、其他子節點的session過期未被呼叫也會丟擲異常?但是不影響自身節點的使用

org.apache.zookeeper.KeeperException$SessionExpiredException: KeeperErrorCode = Session expired for /esque2

/* 2、建立根節點下的子節點時會拋根節點不為空的異常?但是不影響子節點的建立

org.apache.zookeeper.KeeperException$NotEmptyException: KeeperErrorCode = Directory not empty for /confTest */(因為呼叫了delete方法去刪除根節點)

/*3、多個執行緒同時對一個子服務的節點進行修改, 會對其產生影響*/(建立持久順序節點)

4、如果寫操作建立了臨時節點,釋放之後讀操作無法獲取

5、介面回撥方法的執行依賴於主執行緒的阻塞時間,如果在回撥方法中呼叫其他子服務的介面,會執行了一半之後停止

相關推薦

zookeeper-watcher非同步呼叫服務

zookeeper=檔案系統+通知機制 一、 檔案系統 Zookeeper維護一個類似檔案系統的資料結構: 每個子目錄項如 NameService 都被稱作為 znode,和檔案系統一樣,我們能夠自由的增加、刪除znode,在一個znode下增加、刪除子znode,唯

Anthem 非同步呼叫web服務

新增web服務應用 觸發事件: onclick="GetProductsList();" 客戶端js主體: function GetProductsList() { var maxamount = document.getElementBy

Zookeeper-Watcher機制與非同步呼叫原理

atcher機制:目的是為ZK客戶端操作提供一種類似於非同步獲得資料的操作. 1)在建立Zookeeper例項時,允許接收一個watcher引數,此引數將會賦值給watchMnanger.defaultWatcher,成為當前客戶端的預設Watcher.需要注意此wa

【轉】Zookeeper-Watcher機制與非同步呼叫原理

宣告:本文轉載自http://shift-alt-ctrl.iteye.com/blog/1847320,轉載請務必宣告。 Watcher機制:目的是為ZK客戶端操作提供一種類似於非同步獲得資料的操作. 1)在建立Zookeeper例項時,允許接收一個watc

服務優化之非同步呼叫

微服務優化之非同步呼叫 原文連結 前一節《微服務優化之並行》,主要從並行的角度來提高微服務的響應時間,本節講一下微服務優化之非同步呼叫。非同步的前提是對依賴的RPC介面呼叫,不需要關心其執行結果,對資料沒有強一致性要求,只要能夠達到最終一致性就好。 該種情況下,實現方式一般有兩種: 第一

Dubbo剖析-服務消費端非同步呼叫

一、前言 前面我們講解的無論是正常呼叫還是泛化呼叫也好,都是進行同步呼叫的,也就是服務消費方發起一個遠端呼叫後,呼叫執行緒要被阻塞掛起,直到服務提供方返回。本節來講解下非同步呼叫,非同步呼叫是指服務消費方發起一個遠端呼叫後,不等服務提供方返回結果,呼叫方法就返回了,也就是當前執行緒不會被阻塞,這就允許呼叫方

spring4學習記錄08-呼叫遠端服務RPC(非同步,activeMQ)

簡介 上一篇文章說的是應用之間同步進行互動的場景,這裡介紹非同步的使用。 概念 同步,當客戶端呼叫遠端方法時,客戶端必須等待遠端方法完成之後,才能繼續執行,即使遠端方法並不返回任何訊息,客戶端也必須阻塞到服務完成。 非同步,客戶端不需要等待伺服器處理

Web服務下的非同步呼叫

通過非同步呼叫機制,可以提高程式的執行效率,同時,給使用者良好的介面體驗。 .net2.0下提供了很好的機制來支援Web服務的非同步呼叫。 下面通過一個例子來說明Web服務下怎樣實現非同步呼叫。 首先先建立一個Web服務專案 publicclass MyService : 

C# 多執行緒詳解 Part.02(UI 執行緒和執行緒的互動、ProgressBar 的非同步呼叫

       我們先來看一段執行時會丟擲 InvalidOperationException 異常的程式碼段: private void btnThreadA_Click(object sender, EventArgs e) { Thread thread

ZooKeeper非同步呼叫命令

在ZooKeeper中,所有的同步呼叫命令,都會有一個相應的非同步呼叫方法。非同步呼叫能在一個單獨執行緒中同時提交更多的命令,也能在一定程度上簡化程式碼實現。 1 非同步create方法 如建立zNode的命令create,同步方法的定義是 /** * @param path 建立節點的路徑 * @p

java.lang.NoClassDefFoundError: org/apache/zookeeper/Watcher$Event$KeeperState

create col cycle eve apach sport fig depend frame 七月 29, 2017 10:51:00 上午 org.apache.catalina.core.StandardContext listenerStart嚴重: Excep

zookeeper-Watcher

create nod RoCE 客戶 public pub oid child .com   zookeeper的客戶端會從它連接的服務端接收到各種消息,通過註冊實現Watcher接口就可以來處理這些事件。 類圖結構    Watcher   消息處理接口。 public

Zookeeper-watcher機制源碼分析(一)

exc class sso referer 告訴 resp sessionid chm 同學 Watcher的基本流程 ZooKeeper 的 Watcher 機制,總的來說可以分為三個過程:客戶端註冊 Watcher、服務器處理 Watcher 和客戶端回調 Watche

dubbo系列二、dubbo+zookeeper+dubboadmin分布式服務框架搭建(windows平臺)

limit send dem ring 分布 gui ref urn standard 一、zookeeper配置中心安裝 1、下載安裝包,zookeeper-3.4.6.tar.gz 2、解壓安裝包,修改配置文件 參考zookeeper-3.4.6/co

ZooKeeper Watcher

客戶端 包含 事件 eve 客戶端設置 類型 ffffff 才會 訂閱者 ZooKeeper 提供了分布式數據發布/訂閱功能,一個典型的發布/訂閱模型系統定義了一種一對多的訂閱關系,能讓多個訂閱者同時監聽某一個主題對象,當這個主題對象自身狀態變化時,會通知所有訂閱者,使他們

SpringBoot ——非同步呼叫Async

什麼是非同步呼叫? 非同步呼叫是相對於同步呼叫而言的,同步呼叫是指程式按預定順序一步步執行,每一步必須等到上一步執行完後才能執行,非同步呼叫則無需等待上一步程式執行完即可執行。 如何實現非同步呼叫? 多執行緒,這是很多人第一眼想到的關鍵詞,沒錯,多執行緒就是一種實現非同步呼叫的方式。

C# 委託的同步呼叫非同步呼叫--抓住重點

委託的Invoke方法用來進行同步呼叫。同步呼叫也可以叫阻塞呼叫,它將阻塞當前執行緒,然後執行呼叫,呼叫完畢後再繼續向下進行。 同步呼叫的例子: using System; using System.Threading; public delegate int AddHandl

SpringBoot 處理非同步呼叫的示例

Springboot中集成了@Async註解,我們在使用的時候直接用就好了.     不需要獲取到返回值 如果只是單純的讓執行緒去非同步執行,不需要返回結果的話,如下示例,直接進行..單執行緒進行的話,至少需要4+3+2=9秒鐘,而我們不考慮執行的結果,只是讓他去

小程式學習之旅----slot 元件呼叫父元件的方法、父元件呼叫元件的方法

slot子元件 <!--pages/user/user.wxml--> <header title='{{title}}'></header> {{title}} <footer> <button>我是footer子元件裡的按鈕&l

SpringCloud分散式事務實戰(七)在微服務1中建立整合函式,呼叫服務2

(1) 新增jar pom.xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-s