CuratorFramework

Curator框架提供了一套高级的API, 简化了ZooKeeper的操作。

话不多说,看代码

package com.donews.data.util

import java.util.concurrent.TimeUnit

import kafka.common.TopicAndPartition
import org.apache.curator.framework.CuratorFrameworkFactory
import org.apache.curator.framework.recipes.locks.InterProcessMutex
import org.apache.curator.framework.recipes.nodes.PersistentEphemeralNode
import org.apache.curator.retry.ExponentialBackoffRetry
import org.apache.zookeeper.CreateMode
import org.slf4j.LoggerFactory
import java.util.{List => JList} import com.donews.data.Config import scala.collection.JavaConversions._
/**
* Created by reynold on 17-3-20.
*/
object ZookeeperHelper {
val LOG = LoggerFactory.getLogger(ZookeeperHelper.getClass)
val client = {
val client = CuratorFrameworkFactory
.builder
.connectString(Config.ZOOKEEPER_CONNECT)
.retryPolicy(new ExponentialBackoffRetry(1000, 3))
.namespace("reynold")
.build()
client.start()
client
}

//传入path,将path上锁
def lock(path: String)(body: => Unit) {
val lock = new InterProcessMutex(client, path)
lock.acquire()
try {
body
} finally {
lock.release()
} }

//将路径上锁然后执行body里面的程序
def tryDo(path: String)(body: => Unit): Boolean = {
val lock = new InterProcessMutex(client, path)
if (!lock.acquire(10, TimeUnit.SECONDS)) {
LOG.info(s"不能获得锁 {$path},已经有任务在运行,本次任务退出")
return false
}
try {
LOG.info("获准运行")
body
true
} finally {
lock.release()
LOG.info(s"释放锁 {$path}")
} } //zookeeper创建路径
def ensurePathExists(path: String): Unit = {
if (client.checkExists().forPath(path) == null) {
client.create().creatingParentsIfNeeded().forPath(path)
}
} //zookeeper加载offset的方法
def loadOffsets(topicSet: Set[String], defaultOffset: Map[TopicAndPartition, Long]): Map[TopicAndPartition, Long] = {
val kafkaOffsetPath = s"/kafkaOffsets"
ensurePathExists(kafkaOffsetPath)
val offsets = for {
//t就是路径webstatistic/kafkaOffsets下面的子目录遍历
t <- client.getChildren.forPath(kafkaOffsetPath)
if topicSet.contains(t)
//p就是新路径 /reynold/kafkaOffsets/donews_website
p <- client.getChildren.forPath(s"$kafkaOffsetPath/$t")
} yield {
//遍历路径下面的partition中的offset
val data = client.getData.forPath(s"$kafkaOffsetPath/$t/$p")
//将data变成Long类型
val offset = java.lang.Long.valueOf(new String(data)).toLong
(TopicAndPartition(t, Integer.parseInt(p)), offset)
} defaultOffset ++ offsets.toMap
} //zookeeper存储offset的方法
def storeOffsets(offsets: Map[TopicAndPartition, Long]): Unit = {
val kafkaOffsetPath = s"/kafkaOffsets"
if (client.checkExists().forPath(kafkaOffsetPath) == null) {
client.create().creatingParentsIfNeeded().forPath(kafkaOffsetPath)
}
for ((tp, offset) <- offsets) {
val data = String.valueOf(offset).getBytes
val path = s"$kafkaOffsetPath/${tp.topic}/${tp.partition}"
ensurePathExists(path)
client.setData().forPath(path, data)
}
} def main(args: Array[String]) {
// println(Config.ZOOKEEPER_CONNECT)
// tryDo("/locks/test"){
// println("hello world")
// }
// val n=new PersistentEphemeralNode(client,PersistentEphemeralNode.Mode.EPHEMERAL,"/appstatistic/test","hello".getBytes)
// n.start()
// client.setData().forPath("/appstatistic/test","xxx".getBytes)
// val kafkaParams = Map[String, String](
// "metadata.broker.list" -> "spark-slave03:9092,spark-slave04:9092,spark-slave05:9092"
// )
// val kafka = new KafkaClusterHelper(kafkaParams)
// val offsets = kafka.getFromOffsets(kafkaParams, Set("donews"))
// println(offsets)
// storeOffsets(offsets)
loadOffsets(Set("donews"), Map()).foreach(println(_))
// val done=tryDo("/appstatistic/batchMainx") {
// println("it works")
// Thread.sleep(1000L*35)
// }
// println(done)
}
}

Zookeeper开源客户端框架Curator的使用的更多相关文章

  1. Zookeeper开源客户端框架Curator简介

    Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情 ...

  2. Zookeeper开源客户端框架Curator简介[转]

    Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情 ...

  3. zookeeper开源客户端curator

    zookeeper的原生api相对来说比较繁琐,比如:对节点添加监听事件,当监听触发后,我们需要再次手动添加监听,否则监听只生效一次:再比如,断线重连也需要我们手动代码来判断处理等等.对于curato ...

  4. 八:Zookeeper开源客户端Curator的api测试

    curator是Netflix公司开源的一套ZooKeeper客户端,Curator解决了很多ZooKeeper客户端非常底层的细节开发工作.包括连接重连,反复注册Watcher等.实现了Fluent ...

  5. Zookeeper开源客户端Curator之创建会话

    前面Zookeeper的链接使用的都是其提供的原生代码,实际开发过程中非常底层的细节开发工作如连接重连,反复注册等耗费开发人员大量的工作精力并且重复工作.而开源客户端Curator的出现解决了该类问题 ...

  6. Zookeeper开源客户端Curator的使用

    开源zk客户端-Curator 创建会话: RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3); CuratorFramewor ...

  7. Zookeeper开源客户端Curator之事件监听详解

    Curator对Zookeeper典型场景之事件监听进行封装,提供了使用参考.这篇博文笔者带领大家了解一下Curator的实现方式. 引入依赖 对于Curator封装Zookeeper的典型场景使用都 ...

  8. 七:zooKeeper开源客户端ZkClient的api测试

    ZkClient是Gitthub上一个开源的ZooKeeper客户端.ZKClient在ZooKeeper原生API接口之上进行了包装,是一个更加易用的ZooKeeper客户端.同时ZKClient在 ...

  9. ZooKeeper(3.4.5) - 开源客户端 Curator(2.7.0) 的简单示例

    一.创建会话 1. 创建会话 package com.huey.dream.demo; import org.apache.curator.framework.CuratorFramework; im ...

随机推荐

  1. 干货 | 京东技术中台的Flutter实践之路

    在 2019 年,Flutter 推出了多个正式版本,支持的终端越来越多,使用的项目也越来越多.Flutter 正在经历从小范围尝鲜到大面积应用的过程,越来越多的研发团队加入到 Flutter 的学习 ...

  2. C语言-再论指针与数组

    指针与数组的天生姻缘1.以指针方式来访问数组元素(1).数组元素使用时不能整体访问,只能是单个访问.访问形式有两种:数组形式和指针形式.(2).数组形式访问数组元素:数组名[下标]:(下标从0开始(3 ...

  3. Linux系统相关命令

    时间和日期 date cal 磁盘和目录空间 df du 进程信息 ps top kill 01. 时间和日期 序号 命令 作用 01 date 查看系统时间 02 cal calendar 查看日历 ...

  4. selenium浏览器内核监测处理

    一.代码 from selenium.webdriver import Chrome from selenium.webdriver import ChromeOptions option = Chr ...

  5. // 生成modbus CRC16数据

    CRC- / MODBUS : )CRC寄存器初始值为 FFFF:即16个字节全为1: )CRC- / MODBUS的多项式A001H ( 0001B) ‘H’表示16进制数,‘B’表示二进制数 计算 ...

  6. Java正则表达式基础知识整理

    指定为字符串的正则表达式必须首先被编译为此类的实例.然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配.执行匹配所涉及的所有状态都驻留在匹配器中,所以多个 ...

  7. Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path). BitcoinJSONRPCClient异常、及其他异常

    1.异常信息 Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path) ...

  8. ZJNU 1213 - 取水——高级

    某个村庄i可以打一口井取水花费费用Wi,也可以与有水的村庄连接取水 又因为不可能没有一个村庄不打井(即至少有一个村庄打井,其余村庄连向它) 实际上就可以理解为,将水井看作第N+1个村庄,需要有村庄与这 ...

  9. QeePHP

    百度百科: https://baike.baidu.com/item/qeephp/8328612?fr=aladdin 官方地址: http://www.qeephp.cn/app/index.ph ...

  10. Python笔记_第二篇_面向过程_第二部分_4.常用模块的简单使用_import语句的解释

    1. import语句.from...import语句.from...import*语句 解释:注意一定要在体同一级目录下 1.1 引入模块 格式:import module[,module2,... ...