zookeeper-05-javaAPI使用

[TOC]

本文主要記錄自己學(xué)習(xí)zookeeper時(shí)的一些個(gè)人筆記。不喜勿噴募疮。

1 環(huán)境準(zhǔn)備

隨便建個(gè)java項(xiàng)目即可。

maven坐標(biāo):

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.9</version>
</dependency>

2 同步方式調(diào)用

public class ZKTestSync {

    public static String connectStr = "192.168.161.128:2181";
    public ZooKeeper keeper = null;
    private static Stat stat = new Stat();
    private static Logger log = LoggerFactory.getLogger(ZKTestSync.class);

    @Before
    public void init() {
        try {
            keeper = new ZooKeeper(connectStr, 3000, (WatchedEvent event) -> {
                log.info("事件:{}", event);
                if (event.getState() == KeeperState.SyncConnected) {
                    if (event.getType() == EventType.None && event.getPath() == null) {

                    } else {
                        if (event.getType() == EventType.NodeChildrenChanged) {
                            log.info("節(jié)點(diǎn){}發(fā)生變化", event.getPath());
                        } else if (EventType.NodeDataChanged == event.getType()) {
                            try {
                                log.info("節(jié)點(diǎn){}數(shù)據(jù)發(fā)生變化", event.getPath());
                                this.keeper.getData(event.getPath(), false, stat);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @After
    public void close() {
        if (keeper != null)
            try {
                keeper.close();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }

    @Test
    public void testCreateNode() {
        try {
            String string = this.keeper.create("/node_3", "3".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println(string);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testGetChildren() {
        try {
            List<String> list = this.keeper.getChildren("/", false);
            list.stream().forEach(System.out::println);

            // true表示對(duì)節(jié)點(diǎn)的變化感興趣,
            // 在節(jié)點(diǎn)變化時(shí)在ZooKeeper構(gòu)造函數(shù)傳入的Watcher中可收到通知.
            // 但是這種監(jiān)聽器只是一次性的
            list = this.keeper.getChildren("/", true);
            list.stream().forEach(System.out::println);
            Thread.sleep(3 * 60 * 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testGetData() {
        try {
            String str = new String(this.keeper.getData("/node_8", true, stat));
            System.out.println(str);
            Thread.sleep(3 * 60 * 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testDelete() {
        try {
            this.keeper.delete("/node_40000000005", -1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testSetData() {
        try {
            Stat s = this.keeper.setData("/node_1", "ddd".getBytes(), -1);
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testSetACL() {
        try {
            ACL ipAcl = new ACL(Perms.CREATE | Perms.DELETE | Perms.READ, new Id("ip", "192.168.161.1"));
            ACL digestAcl = new ACL(Perms.READ | Perms.WRITE, new Id("digest", DigestAuthenticationProvider.generateDigest("hylexus:123456")));
            List<ACL> acls = Arrays.asList(ipAcl, digestAcl);
            String string = this.keeper.create("/node_11", "8".getBytes(), acls, CreateMode.PERSISTENT);
            System.out.println(string);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testGenerateDigest() throws NoSuchAlgorithmException {
        System.out.println(DigestAuthenticationProvider.generateDigest("hylexus:123"));
    }

}

3 異步方式調(diào)用

和上面的同步代碼的最大區(qū)別就是僻弹,異步代碼沒法及時(shí)獲取返回值阿浓,或者說他沒有返回值。
只能通過提供回調(diào)函數(shù)的方式來處理操作完成后的工作蹋绽。
但是有了回調(diào)函數(shù)芭毙,難免代碼中有大量匿名類,為簡(jiǎn)單卸耘,此處使用java8的lambda代替匿名類退敦。

public class ZKTestASync {

    public static String connectStr = "192.168.161.128:2181";
    public ZooKeeper keeper = null;
    private static final Logger log = LoggerFactory.getLogger(ZKTestASync.class);
    private static Stat stat = new Stat();

    @Before
    public void init() {
        try {
            keeper = new ZooKeeper(connectStr, 3000, (WatchedEvent event) -> {
                log.info("事件:{}", event);
                if (event.getState() == KeeperState.SyncConnected) {
                    if (event.getType() == EventType.None && event.getPath() == null) {

                    } else {
                        if (event.getType() == EventType.NodeChildrenChanged) {
                            log.info("節(jié)點(diǎn){}發(fā)生變化", event.getPath());
                        } else if (EventType.NodeDataChanged == event.getType()) {
                            try {
                                log.info("節(jié)點(diǎn){}數(shù)據(jù)發(fā)生變化", event.getPath());
                                this.keeper.getData(event.getPath(), false, stat);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @After
    public void close() {
        if (keeper != null)
            try {
                keeper.close();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }

    // 異步創(chuàng)建
    @Test
    public void testCreateNodeASync() {
        // 異步調(diào)用,沒有返回值,通過回調(diào)函數(shù)處理結(jié)果
        this.keeper.create("/node_4", "3".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL, new StringCallback() {
            /***
             * @param rc:返回碼
             * @param path:要?jiǎng)?chuàng)建的節(jié)點(diǎn)的完整路徑(想要?jiǎng)?chuàng)建的路徑)
             * @param ctx:create方法傳入的上下文參數(shù),此處是
             *            "testCreateNodeASync"
             * @param name:返回的創(chuàng)建的真實(shí)路徑(創(chuàng)建順序節(jié)點(diǎn)時(shí)返回的真實(shí)路徑和傳入的路徑是不同的)
             */
            @Override
            public void processResult(int rc, String path, Object ctx, String name) {
                log.info("rc:{}", rc);
                log.info("path:{}", path);
                log.info("ctx:{}", ctx);
                log.info("name:{}", name);
            }
        }, "testCreateNodeASync");
    }

    @Test
    public void testGetChildren() {
        try {
            /***
             * @param rc:返回碼
             * @param path:要?jiǎng)?chuàng)建的節(jié)點(diǎn)的完整路徑(想要?jiǎng)?chuàng)建的路徑)
             * @param ctx:create方法傳入的上下文參數(shù)
             * @param children:子節(jié)點(diǎn)列表
             * @param stat:節(jié)點(diǎn)狀態(tài)
             */
            this.keeper.getChildren("/", true, //
                    (int rc, String path, Object ctx, List<String> children, Stat stat) -> {
                        log.info("rc:{}", rc);
                        log.info("path:{}", path);
                        log.info("ctx:{}", ctx);
                        log.info("children:{}", children);
                        log.info("stat:{}", stat);
                    }, "這里可以傳入任何Object作為上下文以便在回調(diào)函數(shù)函數(shù)中使用");
            Thread.sleep(3 * 60 * 100);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testGetData() {
        try {
            this.keeper.getData("/node_1", true, (int rc, String path, Object ctx, byte[] data, Stat stat) -> {
                log.info("rc:{}", rc);
                log.info("path:{}", path);
                log.info("ctx:{}", ctx);
                log.info("data:{}", new String(data));
                log.info("stat:{}", stat);
            }, null);
            Thread.sleep(3 * 60 * 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testDelete() {
        try {
            this.keeper.delete("/node_6", -1, (int rc, String path, Object ctx) -> {
                log.info("rc:{}", rc);
                log.info("path:{}", path);
                log.info("ctx:{}", ctx);
            }, null);
            Thread.sleep(3 * 60 * 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testSetData() {
        try {
            this.keeper.setData("/node_1", "aaa".getBytes(), -1, (int rc, String path, Object ctx, Stat stat) -> {
                log.info("rc:{}", rc);
                log.info("path:{}", path);
                log.info("ctx:{}", ctx);
                log.info("stat:{}", stat);
            }, null);
            Thread.sleep(3 * 60 * 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4 總結(jié)

  • 整個(gè)API還是簡(jiǎn)單易用的
  • 注冊(cè)的監(jiān)聽器只是一次性的,沒有提供類似于自動(dòng)注冊(cè)多次的API
  • session的超時(shí)重連可能導(dǎo)致watcher的重復(fù)執(zhí)行蚣抗,需要手動(dòng)自己控制
  • 返回值中還有的是byte[],入?yún)⒁灿衎yte[]侈百。操作不是很舒服

當(dāng)然,也有zookeeper編程的其他框架可用翰铡,比如ZkClient等

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钝域,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锭魔,更是在濱河造成了極大的恐慌例证,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迷捧,死亡現(xiàn)場(chǎng)離奇詭異织咧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)漠秋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門烦感,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人膛堤,你說我怎么就攤上這事∩胃茫” “怎么了肥荔?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵绿渣,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我燕耿,道長(zhǎng)中符,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任誉帅,我火速辦了婚禮楔脯,結(jié)果婚禮上属愤,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好恶复,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著告喊,像睡著了一般闪檬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上氛悬,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天则剃,我揣著相機(jī)與錄音,去河邊找鬼如捅。 笑死棍现,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的镜遣。 我是一名探鬼主播己肮,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼烈涮!你這毒婦竟也來了朴肺?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤坚洽,失蹤者是張志新(化名)和其女友劉穎戈稿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讶舰,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鞍盗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跳昼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片般甲。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鹅颊,靈堂內(nèi)的尸體忽然破棺而出敷存,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布锚烦,位于F島的核電站觅闽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏涮俄。R本人自食惡果不足惜蛉拙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望彻亲。 院中可真熱鬧孕锄,春花似錦、人聲如沸苞尝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽野来。三九已至恼除,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曼氛,已是汗流浹背豁辉。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舀患,地道東北人徽级。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像聊浅,于是被迫代替她去往敵國(guó)和親餐抢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理低匙,服務(wù)發(fā)現(xiàn)旷痕,斷路器,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • 一顽冶、ZooKeeper的背景 1.1 認(rèn)識(shí)ZooKeeper ZooKeeper---譯名為“動(dòng)物園管理員”欺抗。動(dòng)物...
    algernoon閱讀 9,071評(píng)論 1 106
  • 用消費(fèi),麻痹自己
    小陸_10a4閱讀 114評(píng)論 0 0
  • 在靜夜里隨想 內(nèi)心的波瀾 時(shí)而起伏時(shí)而跌宕 兀自反問 如果屈原沒有投江 流水會(huì)不會(huì)嗚咽 山河會(huì)不會(huì)淪喪 歷史會(huì)不會(huì)...
    安言靜語閱讀 515評(píng)論 0 1
  • 第二周的思考與分享 上周二的課上强重,劉老師講绞呈,靜心就是檢索自己,看自己處于什么狀態(tài)间景,后面講能量層級(jí)佃声,吧啦吧啦講了好多...
    巨曉松閱讀 707評(píng)論 0 1