1. 程式人生 > >ZooKeeper Watch 回撥事件丟失

ZooKeeper Watch 回撥事件丟失

ZooKeeper 在官網著重提示在使用 Watch 的時候要注意:
  • Watch 是一次性的,如果 watch 事件發生了,還想 watch 需要再設定新的watch
  • 因為 watch 的一次性,再次註冊 watch 的網路延遲,所以 znode 每次變更不可能都 watch 到
  • 一個 watch 物件或者函式/上下文對(pair),只會觸發一次。比如,如果相同的 watch 物件註冊了 exist 和 getData 呼叫在相同檔案,並且檔案已經被刪除,watch 物件只會在檔案被刪除觸發一次
  • 當你與一個服務斷開(比如zk服務宕機),你將不會獲得任何 watch,直到連線重連。因此,session 事件將會發送給所有 watch 處理器。使用 session 事件進入一個安全模式:當斷開連線的時候將不會收到任何事件,因此您的程序應該以該模式保守執行

用程式碼表現一下 Watch 回撥事件丟失:

package com.wenniuwuren.zookeeper.curator.watch;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;


import com.wenniuwuren.Constants;

/**
 * Zookeeper之Watcher監聽事件丟失
 *
 * @author wenniuwuren
 */
public class WatchLost {

    static String path = "/test/watchlost1";
    static CuratorFramework client = CuratorFrameworkFactory.builder().connectString(Constants.ZK_HOST)
            .retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();

    public static void main(String[] args) {
        try {
            client.start();

            final NodeCache nodeCache = new NodeCache(client, path);
            nodeCache.start();

            if (client.checkExists().forPath(path) == null)
                client.create().forPath(path, "0".getBytes());

            nodeCache.getListenable().addListener(new NodeCacheListener() {
                @Override
                public void nodeChanged() throws Exception {
                    if (nodeCache.getCurrentData() == null) {
                        System.out.println("節點被刪除");
                    } else {
                        System.out.println("節點當前內容為:" + new String(nodeCache.getCurrentData().getData()));
                    }

                }
            });

            client.setData().forPath(path, "1".getBytes());
            client.setData().forPath(path, "2".getBytes());
            client.setData().forPath(path, "3".getBytes());
            client.setData().forPath(path, "4".getBytes());
            client.setData().forPath(path, "5".getBytes());
            client.setData().forPath(path, "6".getBytes());
            client.setData().forPath(path, "7".getBytes());
            client.setData().forPath(path, "8".getBytes());
            client.setData().forPath(path, "9".getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

多次的執行結果:
執行結果一:
節點當前內容為:9
節點當前內容為:3
節點當前內容為:4
節點當前內容為:5
節點當前內容為:6
節點當前內容為:7
節點當前內容為:8
節點當前內容為:9

執行結果二:
節點當前內容為:9
節點當前內容為:2
節點當前內容為:3
節點當前內容為:4
節點當前內容為:5
節點當前內容為:6
節點當前內容為:7
節點當前內容為:8
節點當前內容為:9

執行結果三:
節點當前內容為:9
節點當前內容為:3
節點當前內容為:4
節點當前內容為:6
節點當前內容為:7
節點當前內容為:8
節點當前內容為:9

執行幾次,可以看到,並不是每次 client 都是收到 watch 回撥,會漏掉幾次。所以在使用 ZooKeeper Watch 的時候,不能覺得監聽回撥一定會成功,所以在寫程式碼的時候要注意這一點。

相關推薦

ZooKeeper Watch 事件丟失

ZooKeeper 在官網著重提示在使用 Watch 的時候要注意: Watch 是一次性的,如果 watch 事件發生了,還想 watch 需要再設定新的watch因為 watch 的一次性,再次註

事件監聽,事件

一、事件監聽涉及到三個類物件 1、EventSource(事件源)事件發生的場所 2、Event(事件):事件封裝介面元件上面發生的特定事件 3、EventListener(事件監聽器):負責監聽事件源發生的事件     二、監聽器就是程式中的MyC

[python]select++事件迴圈獲取html

#通過非阻塞io實現http請求 # select + 回撥 + 事件迴圈 # 併發性高 # 使用單執行緒 import socket from urllib.parse import urlparse from selectors import Defau

Document(文件)物件的建立及文件事件

目的 這篇教程將教會你使用 CorelDRAW VBA程式碼來建立和開啟文件,演示 Document 物件的使用方法。 建立文件 Application 物件有兩個方法用來建立文件:CreateDocument 和 CreateDocumentFromTemp

樂鑫Esp32學習之旅⑦ esp32上利用GPIO中斷做一個按鍵的短按和長按的事件,再也無須擔心觸發源。(附帶Demo)

一. 前言; 說到按鍵的短按和長按,很多人都是直接用while(1)死迴圈不斷去讀取按鍵和消抖,通過讀取時間的間隔來確定是長按還是短按!這種方法比較常用,今天的話,小徐給大家帶來的是

laydate時間控制元件繫結事件

1. 下載官網上的壓縮包,解壓laydate 資料夾到專案中; 2. 在頁面引入  <script type="text/javascript" src="js/laydate/laydate.js"></script> 3. 在頁面新增:  input框設定:<inp

Android 的介面事件

看見網上一些回撥的解釋都很複雜的,特別基於Android的自定義回撥,感覺一頭霧水,於是乎,我也寫了這篇基於我對回撥的解釋。 先來看一個簡單的例子: 有兩個類 ClassA ,和 ClassB, ClassA呼叫ClassB裡面的方法, public class Cla

php監聽redis key失效觸發事件

一、需求分析: 1、設定了生命時間的key,過期的時候能不能提示,能夠監聽過期的key? 2、怎樣用redis實現定時任務? 二、應用場景: 在我們程式中經常會有需要定時執行的程式,比如:商品下單後半小時內不支付自動撤單等等。 最簡單粗暴的辦法,就是寫一個程式,讓它定時執行,

ZooKeeper系統模型之Watcher——資料變更的通知(介面、事件方法)。

        ZooKeeper提供了分散式資料的釋出/訂閱功能。一個典型的釋出/訂閱模型系統定義了一種一對多的訂閱關係,能夠讓多個訂閱者同時監聽某一個主題物件,當這個主題物件自身狀態變化時,會通知所有訂閱者,使他們能夠做出相應的處理。在ZooKeeper中,引入了Wat

Unity 接收 IOS 記憶體不足的事件

1. unity 2017 新版本 https://docs.unity3d.com/ScriptReference/Application-lowMemory.html 直接註冊一下事件 2. 5.5 左右的 需要自己和IOS關聯起來。 方法一.用 XUPorter 工具 修改程式碼

Zookeeper C API之函式

監視回撥函式 原型: Typedef void (*watcher_fn)(zhandle_t *zh, int type, int state, const char *path, void *watcherCtx); 監視函式原型的各個引數說明如下:

cocos2d-lua中pageview滑動事件

1.在UIPageView.h中將addEventListener修改為如下 CC_DEPRECATED_ATTRIBUTE void addEventListener(const ccPageViewCallback& callback); using Scrol

Dubbo、Spring、Zookeeper、整合基礎案例(引數)

摘要:最近抽時間系統的學習了Dubbo的一些內容,趁有時間,整理下,順便記錄下,以防以後回顧。前面我們學校了Dubbo的xml、註解方式,本次我們學習下Dubbo的引數回撥。 一:執行環境 1>

JS-呼叫棧、事件迴圈、訊息佇列(也叫任務隊和佇列)、作業佇列(微任務佇列)

一:呼叫棧是個什麼鬼東西,它具有棧的屬性--後進先出 先看一段簡單的JS程式碼: const second = function(){ console.log('hello there'); } const first = function() { console.log('hi,first'); secon

介紹一下eventpp,我的開源C++ 事件派發和程式碼庫

我(wqking)開發,使用標準C++11規範。 eventpp是一個 C++ 事件庫,它提供的工具允許應用程式元件通過排程事件並監聽它們來相互通訊。使用eventpp,您可以非常輕鬆地實現訊號/插槽機制或觀察者模式。 特性 支援同步事件排程和非同步事件佇列。 可配

C#公眾平臺(二)—— 接收事件推送之關注

在C#公眾平臺(一)—— 接入配置 寫了公眾平臺的基本配置,這篇文章講的是關注回撥事件。 基礎幫助類 接收事件推送文件 接入指南 /// <summary> /// WeChatEvent 的摘要說明 /// </summary>

非同步、事件驅動、協程概念辨析

同步和非同步: 面試問題什麼是非同步非阻塞 A. 同步 所謂同步,就是在發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回。 B. 非同步 非同步的概念和同步相對。 當一個非同步過程呼叫發出後,先返回,呼叫者不會立刻得到結果。 實際處理這個呼叫的部件是在呼叫發出後, 通過狀態、通知來通知

Android中點選事件介面踩坑心得

有時候寫程式碼的時候有這樣的功能要求,如在ListView或recyclerView中的Item中的控制元件(如Button,TextView)上添加回調介面事件。其實難點就在添加回調介面事件上,怎麼寫介面,介面回撥在哪裡,這才是關鍵。下面是個例子: 介面的寫法:一下是兩介

Zookeeper C API之函式

監視回撥函式 原型: Typedef void (*watcher_fn)(zhandle_t *zh, int type, int state, const char *path, void *watcherCtx); 監視函式原型的各個引數說明如下:

Qt 學習之路 2(19):事件的接受與忽略(當重寫事件回撥函式時,時刻注意是否需要通過呼叫父類的同名函式來確保原有實現仍能進行!有好幾個例子。為什麼要這麼做?而不是自己去手動呼叫這兩個函式呢?因為我們無法確認父類中的這個處理函式有沒有額外的操作)

版本: 2012-09-29 2013-04-23 更新有關accept()和ignore()函式的相關內容。 2013-12-02 增加有關accept()和ignore()函式的示例。 上一章我們介紹了有關事件的相關內容。我們曾經提到,事件可以依情況接受和忽略。現在,我們就