ZooKeeper(4)Java API

来源:互联网 发布:第一个程序员名字 编辑:程序博客网 时间:2024/05/20 08:23

创建ZooKeeper客户端

这里写图片描述

其中CanBeReadOnly的含义蛮有意思:在ZooKeeper集群中,如果一个机器出故障了,与半数以上机器失去联系,按理说是不能提供服务了。在特殊情况下(几乎不写的情况),还是希望它提供读服务。

object MyWatcher : Watcher{    override fun process(event: WatchedEvent?) {        when (event?.type){            Watcher.Event.EventType.NodeCreated                    -> println("path create : ${event.path}")            Watcher.Event.EventType.NodeChildrenChanged                    -> println("child changed in : ${event.path}")            else -> println("UnKnown event")        }    }}object ZKManager{    //服务器列表    val hostPort = "localhost:2181,localhost:2182,localhost:2183"    //心跳检测超时时长    val sessionTime = 5000    //事件监听器    val watcher = MyWatcher    //是否只读,默认false    val canBeReadOnly = false    //会话重用ID    var sessionId: Long? = null    //会话重用密码    var sessionPWD: ByteArray? = null    var zk: ZooKeeper? = null    fun getZooKeeper(Id: Long? = sessionId,                     PWD: ByteArray? = sessionPWD,                     newSession: Boolean = false,                     anotherSessin: Boolean = false): ZooKeeper? {        if (anotherSessin){            return ZooKeeper(hostPort, sessionTime, watcher)        }        if (sessionId != null && sessionPWD != null){            zk?.close()            zk = ZooKeeper(hostPort, sessionTime, watcher, Id!!,PWD)        }        if (newSession || (zk == null)){            zk?.close()            zk = ZooKeeper(hostPort, sessionTime, watcher)        }        return zk    }    fun saveSession(){        sessionId = zk?.sessionId        sessionPWD = zk?.sessionPasswd    }}fun main(args: Array<String>){    val zk = ZKManager.getZooKeeper()    println("The State is ${zk?.state} and the sesion is ${zk?.sessionId}")    println("id: ${zk?.sessionId} => ${zk?.sessionPasswd}")    val otherZk = ZKManager.getZooKeeper(anotherSessin = true)    println("The State is ${otherZk?.state} and the sesion is ${otherZk?.sessionId}")    println("id: ${otherZk?.sessionId} => ${otherZk?.sessionPasswd}")    ZKManager.saveSession()    val reloadZk = ZKManager.getZooKeeper()    println("The State is ${reloadZk?.state} and the sesion is ${reloadZk?.sessionId}")    println("id: ${reloadZk?.sessionId} => ${reloadZk?.sessionPasswd}")    zk?.close()    otherZk?.close()    reloadZk?.close()}/*The State is CONNECTING and the sesion is 0id: 0 => [B@377dca04The State is CONNECTING and the sesion is 0id: 0 => [B@728938a9UnKnown eventUnKnown eventThe State is CONNECTING and the sesion is 0id: 0 => [B@377dca04UnKnown event*/

创建节点

这里写图片描述

fun ZKManager.createMaster(){    val path = "/master"    val data = "content".toByteArray()    //权限    val acl = ZooDefs.Ids.OPEN_ACL_UNSAFE    //临时节点    val mode = CreateMode.EPHEMERAL    //可以为null,保存上下文信息,可以为一个Session    val context = "I am context"    //回调函数,rc是状态码,path是上面传进去的path    //ctx是上面传入的context, name是成功返回path,否则null    val callback = { rc: Int, path: String?, ctx: Any?, name: String? ->        println("Create path result: [ $rc , $path , real path name:$name ]")    }    //这步创建一下客户端,有则直接返回    getZooKeeper()    this.zk?.create(path,data,acl,mode,callback,context)}fun main(args: Array<String>){    ZKManager.createMaster()    ZKManager.createMaster()    ZKManager.createMaster()    Thread.sleep(10000)}/*Create path result: [ 0 , /master , real path name:/master ]Create path result: [ -110 , /master , real path name:null ]Create path result: [ -110 , /master , real path name:null ]*/

删除节点

这里写图片描述

只允许删除没有子节点的节点,version必须和当前版本一致才能删除成功,如果是-1则和任何版本都一致

获取子节点

这里写图片描述

前4个方法使用ZooKeeper创建时候的Watcher.后4个使用自定义的Watcher

//更改,当NodeChildrenChanged时,列出所有子节点object MyWatcher : Watcher{    override fun process(event: WatchedEvent?) {        when (event?.type){            Watcher.Event.EventType.NodeCreated                    -> println("path create : ${event.path}")            Watcher.Event.EventType.NodeChildrenChanged                    -> println("get child: ${ZKManager.zk?.getChildren(event.path,true)}")            else -> println("UnKnown event")        }    }}fun ZKManager.addChildren(){    val path = "/master/slave"    val data = "".toByteArray()    val acl = ZooDefs.Ids.OPEN_ACL_UNSAFE    val mode = CreateMode.EPHEMERAL_SEQUENTIAL    //在/master上添加监控    val children= this.zk?.getChildren("/master",true)    println(children)    for (i in 1..5){        this.zk?.create(path,data,acl,mode)    }}fun main(args: Array<String>){    ZKManager.createMaster()    ZKManager.addChildren()    Thread.sleep(10000)}/*[]Create path result: [ -110 , /master , real path name:null ]get child: [slave0000000011]get child: [slave0000000011, slave0000000012]get child: [slave0000000011, slave0000000013, slave0000000012]get child: [slave0000000011, slave0000000013, slave0000000012, slave0000000014]get child: [slave0000000011, slave0000000013, slave0000000012, slave0000000015, slave0000000014]*/

获取数据

这里写图片描述

这里写图片描述

version: 和上面一样,CAS的原理

//增加NodeDataChangedobject MyWatcher : Watcher{    override fun process(event: WatchedEvent?) {        when (event?.type){            Watcher.Event.EventType.NodeCreated                    -> println("path create : ${event.path}")            Watcher.Event.EventType.NodeChildrenChanged                    -> println("get child: ${ZKManager.zk?.getChildren(event.path,true)}")            Watcher.Event.EventType.NodeDataChanged                    -> println("data in ${event.path} changed to : ${ZKManager.getData(event.path)}")            else -> println("UnKnown event")        }    }}fun ZKManager.getData(path: String): String{    val path = path    val watch = true    val stat = Stat()    val data: ByteArray = this.zk?.getData(path,watch,stat)!!    return String(data)}fun ZKManager.setData(path: String, data: String){    val path = path    val d = data.toByteArray()    zk?.setData(path, d, -1)}fun main(args: Array<String>){    ZKManager.getZooKeeper()    val d1 = ZKManager.getData("/master")    println(d1)    val executor = Executors.newFixedThreadPool(5)    for (i in 1..5){        executor.execute { ZKManager.setData("/master","content${i}") }        //这里只是为了注册Watcher        val d = ZKManager.getData("/master")    }    executor.shutdown()    Thread.sleep(10000)}/*UnKnown eventcontent5data in /master changed to : content3data in /master changed to : content4data in /master changed to : content5data in /master changed to : content5*/

Exist()

这里写图片描述

这里的watcher会监控创建,删除,更新三种事件

权限控制

有时一个ZooKeeper集群会为很多不同的应用提供服务,这个应用不需要共享数据,因此在不同应用之间有权限问题。

这里写图片描述

schema:控制模式:world,auth,digest,ip和super

auth:具体的权限信息

val zk1 = ZKManager.getZooKeeper(anotherSessin = true)    //声明是只有创建者有权限    val acl = ZooDefs.Ids.CREATOR_ALL_ACL    val mode = CreateMode.EPHEMERAL    //增加权限内容    zk1?.addAuthInfo("digest","foo:true".toByteArray())    zk1?.create("/master","".toByteArray(),acl,mode)    val anotherZK = ZKManager.getZooKeeper(anotherSessin = true)    val data = anotherZK?.getData("/master",false,Stat())    println(String(data!!))    Thread.sleep(20000)/*UnKnown eventUnKnown eventException in thread "main" org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /master*/

但只要加上权限就可以访问了

anotherZK?.addAuthInfo("digest","foo:true".toByteArray())

对删除节点比较特殊,比如创建了/master和/master/one。没有权限则不能删除/master/one

    //创建节点/master,/master/1    val zk1 = ZKManager.getZooKeeper(anotherSessin = true)    val acl = ZooDefs.Ids.CREATOR_ALL_ACL    val mode = CreateMode.PERSISTENT    zk1?.addAuthInfo("digest","foo:true".toByteArray())    zk1?.create("/master","content".toByteArray(),acl,mode)    zk1?.create("/master/1","one".toByteArray(),acl,mode)    Thread.sleep(500)    val zk2 = ZKManager.getZooKeeper(anotherSessin = true)    zk2?.addAuthInfo("digest","foo:true".toByteArray())    zk2?.delete("/master/1",-1)    Thread.sleep(500)    val zk3 = ZKManager.getZooKeeper(anotherSessin = true)    zk3?.delete("/master",-1)
原创粉丝点击