Java curator操作zookeeper获取kafka

Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量。

原文地址:http://blogxinxiucan.sh1.newtouch.com/2017/08/01/Java-curator操作zookeeper获取kafka/

Curator的Maven依赖

    <dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.3.0</version>
</dependency>

本地启动kafka

启动zookeeper

./bin/zookeeper-server-start.sh config/zookeeper.properties

启动kafka

./bin/kafka-server-start.sh config/server.properties

启动kafkaManager

sudo ./bin/kafka-manager

代码

项目结构

先看测试

package com.xinxiucan.test;

import java.util.List;

import com.xinxiucan.api.BrokerApi;
import com.xinxiucan.api.TopicApi;
import com.xinxiucan.zookeeper.ZKBean; public class AppTest { public static void main(String[] args) {
ZKBean zk = new ZKBean();
zk.setZkURL("127.0.0.1:2181");
List<String> ids = BrokerApi.findBrokerIds(zk);
for (String id : ids) {
String idInfo = BrokerApi.findBrokerById(zk, id);
System.out.println(idInfo);
} List<String> topicNames = TopicApi.findAllTopicName(zk);
for (String topicName : topicNames) {
System.out.println("topicName:" + topicName);
} List<String> topics = TopicApi.findAllTopics(zk);
for (String topic : topics) {
System.out.println("topic:" + topic);
} }
}

运行结果

{"jmx_port":-1,"timestamp":"1501636761404","endpoints":["PLAINTEXT://can:9092"],"host":"can","version":3,"port":9092}
topicName:test_xin_1
topicName:xin
topic:{"version":1,"partitions":{"0":[0]}}
topic:{"version":1,"partitions":{"0":[0]}}

剩余代码

ZKBean

package com.xinxiucan.zookeeper;

import java.io.Serializable;

public class ZKBean implements Serializable {

	private static final long serialVersionUID = -6057956208558425192L;

	private int id = -1;

	private String name;

	private String zkURL;

	private String version = "0.8.2.2";

	private boolean jmxEnable;

	private String jmxAuthUsername;

	private String jmxAuthPassword;

	private boolean jmxWithSsl;

	private int zkConnectionTimeout = 30;

	private int maxRetryCount = 3;

	public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getZkURL() {
return zkURL;
} public void setZkURL(String zkURL) {
this.zkURL = zkURL;
} public boolean isJmxEnable() {
return jmxEnable;
} public void setJmxEnable(boolean jmxEnable) {
this.jmxEnable = jmxEnable;
} public String getJmxAuthUsername() {
return jmxAuthUsername;
} public void setJmxAuthUsername(String jmxAuthUsername) {
this.jmxAuthUsername = jmxAuthUsername;
} public String getJmxAuthPassword() {
return jmxAuthPassword;
} public void setJmxAuthPassword(String jmxAuthPassword) {
this.jmxAuthPassword = jmxAuthPassword;
} public boolean isJmxWithSsl() {
return jmxWithSsl;
} public void setJmxWithSsl(boolean jmxWithSsl) {
this.jmxWithSsl = jmxWithSsl;
} public int getZkConnectionTimeout() {
return zkConnectionTimeout;
} public void setZkConnectionTimeout(int zkConnectionTimeout) {
this.zkConnectionTimeout = zkConnectionTimeout;
} public int getMaxRetryCount() {
return maxRetryCount;
} public void setMaxRetryCount(int maxRetryCount) {
this.maxRetryCount = maxRetryCount;
} public String getVersion() {
return version;
} public void setVersion(String version) {
this.version = version;
} @Override
public int hashCode() {
return this.id;
} @Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (obj instanceof ZKBean) {
ZKBean anotherZKCluster = (ZKBean) obj;
return this.id == anotherZKCluster.getId();
} else {
return false;
}
} }

ZKConnectionFactory

package com.xinxiucan.zookeeper;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry; public class ZKConnectionFactory { public static CuratorFramework buildCuratorFramework(ZKBean zk) {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(zk.getZkConnectionTimeout() * 1000, zk.getMaxRetryCount());
CuratorFramework client = CuratorFrameworkFactory.newClient(zk.getZkURL(), retryPolicy);
client.start();
return client;
} }

BrokerApi

package com.xinxiucan.api;

import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.curator.framework.CuratorFramework; import com.xinxiucan.KafkaZKPath;
import com.xinxiucan.zookeeper.ZKBean;
import com.xinxiucan.zookeeper.ZKConnectionFactory; /**
* 获取broker信息
* @author xinxiucan
*/
public class BrokerApi { /**
* 根据zk获取Broker ID列表
* @param zkBean
* @return
*/
public static List<String> findBrokerIds(ZKBean zkBean) {
CuratorFramework client = null;
try {
client = ZKConnectionFactory.buildCuratorFramework(zkBean);
List<String> brokerIdStrs = client.getChildren().forPath(KafkaZKPath.BROKER_IDS_PATH);
return brokerIdStrs;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (client != null) {
client.close();
}
}
} /**
* 根据zk&brokerId获取Broker信息
* @param zkBean
* @return
*/
public static String findBrokerById(ZKBean zkBean, String id) {
CuratorFramework client = null;
try {
client = ZKConnectionFactory.buildCuratorFramework(zkBean);
String brokerIdPath = KafkaZKPath.getBrokerSummeryPath(id);
String brokerInfo = new String(client.getData().forPath(brokerIdPath), "UTF-8");
return brokerInfo;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (client != null) {
client.close();
}
}
} public static Map<String, String> findAllBrokerSummarys(ZKBean zkBean) {
CuratorFramework client = null;
try {
client = ZKConnectionFactory.buildCuratorFramework(zkBean);
List<String> brokerIds = client.getChildren().forPath(KafkaZKPath.BROKER_IDS_PATH);
if (brokerIds == null || brokerIds.size() == 0) {
return null;
}
Map<String, String> brokerMap = new HashMap<String, String>();
for (String brokerId : brokerIds) {
String brokerIdPath = KafkaZKPath.getBrokerSummeryPath(brokerId);
String brokerInfo = new String(client.getData().forPath(brokerIdPath), "UTF-8");
brokerMap.put(brokerId, brokerInfo);
}
return brokerMap;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (client != null) {
client.close();
}
}
} }

TopicApi

package com.xinxiucan.api;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.data.Stat; import com.xinxiucan.KafkaZKPath;
import com.xinxiucan.ReplicasAssignmentBuilder;
import com.xinxiucan.util.Object2Array;
import com.xinxiucan.zookeeper.ZKBean;
import com.xinxiucan.zookeeper.ZKConnectionFactory; /**
* 获取Topic信息
* @author can
*/
public class TopicApi { /**
* 创建Topic
* @param zkBean
* @param topic
* @param partitionsCount
* @param replicationFactorCount
* @param topicConfig
*/
public static void createTopic(ZKBean zkBean, String topic, int partitionsCount, int replicationFactorCount,
Map<String, String> topicConfig) {
CuratorFramework client = null;
try {
client = ZKConnectionFactory.buildCuratorFramework(zkBean);
List<String> brokerIds = client.getChildren().forPath(KafkaZKPath.BROKER_IDS_PATH);
List<Integer> ids = new ArrayList<>();
for (String str : brokerIds) {
int i = Integer.parseInt(str);
ids.add(i);
}
Map<String, List<Integer>> replicasAssignment = ReplicasAssignmentBuilder.assignReplicasToBrokers(ids, partitionsCount,
replicationFactorCount);
Map<String, Object> topicSummaryMap = new HashMap<String, Object>();
topicSummaryMap.put("version", 1);
topicSummaryMap.put("partitions", replicasAssignment);
byte[] topicSummaryData = Object2Array.objectToByteArray(topicSummaryMap);
String topicSummaryPath = KafkaZKPath.getTopicSummaryPath(topic);
Stat stat = client.checkExists().forPath(topicSummaryPath);
if (stat == null) {
// create
client.create().creatingParentsIfNeeded().forPath(topicSummaryPath, topicSummaryData);
} else {
// update
client.setData().forPath(topicSummaryPath, topicSummaryData);
} Map<String, Object> topicConfigMap = new HashMap<String, Object>();
topicConfigMap.put("version", 1);
topicConfigMap.put("config", topicConfig);
byte[] topicConfigData = Object2Array.objectToByteArray(topicConfigMap); String topicConfigPath = KafkaZKPath.getTopicConfigPath(topic);
Stat stat2 = client.checkExists().forPath(topicConfigPath);
if (stat2 == null) {
// create
client.create().creatingParentsIfNeeded().forPath(topicConfigPath, topicConfigData);
} else {
// update
client.setData().forPath(topicConfigPath, topicConfigData);
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (client != null) {
client.close();
}
}
} /**
* 删除Topic
* @param zkBean
* @param topicName
*/
public static void deleteTopic(ZKBean zkBean, String topicName) {
CuratorFramework client = null;
try {
client = ZKConnectionFactory.buildCuratorFramework(zkBean);
String adminDeleteTopicPath = KafkaZKPath.getDeleteTopicPath(topicName);
client.create().creatingParentsIfNeeded().forPath(adminDeleteTopicPath, null);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (client != null) {
client.close();
}
}
} /**
* 查询topic
* @param zkBean
* @return
*/
public static List<String> findAllTopics(ZKBean zkBean) {
CuratorFramework client = null;
try {
client = ZKConnectionFactory.buildCuratorFramework(zkBean);
List<String> topicNames = client.getChildren().forPath(KafkaZKPath.BROKER_TOPICS_PATH);
List<String> topicSummarys = new ArrayList<String>();
for (String topicName : topicNames) {
byte[] topicData = client.getData().forPath(KafkaZKPath.getTopicSummaryPath(topicName));
topicSummarys.add(new String(topicData, "UTF-8"));
}
// add delete flag
List<String> deleteTopics = client.getChildren().forPath(KafkaZKPath.ADMIN_DELETE_TOPICS_PATH);
return topicSummarys;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (client != null) {
client.close();
}
}
} public static List<String> findAllTopicName(ZKBean zkBean) {
CuratorFramework client = null;
try {
client = ZKConnectionFactory.buildCuratorFramework(zkBean);
return client.getChildren().forPath(KafkaZKPath.BROKER_TOPICS_PATH);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (client != null) {
client.close();
}
}
} }

KafkaZKPath

package com.xinxiucan;

public class KafkaZKPath {

	public static final String COMSUMERS_PATH = "/consumers";
public static final String BROKER_IDS_PATH = "/brokers/ids";
public static final String BROKER_TOPICS_PATH = "/brokers/topics";
public static final String CONFIG_TOPICS_PATH = "/config/topics";
public static final String CONFIG_CHANGES_PATH = "/config/changes";
public static final String CONTROLLER_PATH = "/controller";
public static final String CONTROLLER_EPOCH_PATH = "/controller_epoch";
public static final String ADMIN_PATH = "/admin";
public static final String ADMIN_REASSGIN_PARTITIONS_PATH = "/admin/reassign_partitions";
public static final String ADMIN_DELETE_TOPICS_PATH = "/admin/delete_topics";
public static final String ADMIN_PREFERED_REPLICA_ELECTION_PATH = "/admin/preferred_replica_election"; public static String getTopicSummaryPath(String topic) {
return BROKER_TOPICS_PATH + "/" + topic;
} public static String getTopicPartitionsStatePath(String topic,String partitionId) {
return getTopicSummaryPath(topic) + "/partitions/" + partitionId+ "/state";
} public static String getTopicConfigPath(String topic) {
return CONFIG_TOPICS_PATH + "/" + topic;
} public static String getDeleteTopicPath(String topic) {
return ADMIN_DELETE_TOPICS_PATH + "/" + topic;
} public static String getBrokerSummeryPath(String id) {
return BROKER_IDS_PATH + "/" + id;
} public static String getConsumerOffsetPath(String groupId) {
return COMSUMERS_PATH + "/" + groupId +"/offsets";
} public static String getTopicConsumerOffsetPath(String groupId,String topic){
return COMSUMERS_PATH + "/" + groupId +"/offsets/"+topic;
} public static String getTopicPartitionConsumerOffsetPath(String groupId, String topic,String partitionId){
return COMSUMERS_PATH + "/" + groupId +"/offsets/"+topic + "/" + partitionId;
} public static String getTopicPartitionConsumerOwnerPath(String groupId, String topic, String partitionId) {
return COMSUMERS_PATH + "/" + groupId +"/owners/"+topic + "/" + partitionId;
} }

ReplicasAssignmentBuilder

package com.xinxiucan;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random; public class ReplicasAssignmentBuilder { public static Map<String, List<Integer>> assignReplicasToBrokers(List<Integer> brokerListSet, int nPartitions, int nReplicationFactor) {
return assignReplicasToBrokers(brokerListSet, nPartitions, nReplicationFactor, -1, -1);
} /**
* There are 2 goals of replica assignment:
* 1. Spread the replicas evenly among brokers.
* 2. For partitions assigned to a particular broker, their other replicas are spread over the other brokers.
*
* To achieve this goal, we:
* 1. Assign the first replica of each partition by round-robin, starting from a random position in the broker list.
* 2. Assign the remaining replicas of each partition with an increasing shift.
*
* Here is an example of assigning
* broker-0 broker-1 broker-2 broker-3 broker-4
* p0 p1 p2 p3 p4 (1st replica)
* p5 p6 p7 p8 p9 (1st replica)
* p4 p0 p1 p2 p3 (2nd replica)
* p8 p9 p5 p6 p7 (2nd replica)
* p3 p4 p0 p1 p2 (3nd replica)
* p7 p8 p9 p5 p6 (3nd replica)
*/
public static Map<String, List<Integer>> assignReplicasToBrokers(List<Integer> brokerListSet, int nPartitions, int nReplicationFactor,
int fixedStartIndex, int startPartitionId) {
// sort
brokerListSet.sort(new Comparator<Integer>() { @Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
} });
if (nPartitions <= 0) {
throw new RuntimeException("num of partition cannot less than 1");
}
if (nReplicationFactor <= 0) {
throw new RuntimeException("num of replication factor cannot less than 1");
}
if (nReplicationFactor > brokerListSet.size()) {
throw new RuntimeException("broker num is less than replication factor num");
} Random random = new Random(); Map<String, List<Integer>> result = new HashMap<String, List<Integer>>();
int startIndex = fixedStartIndex >= 0 ? fixedStartIndex : random.nextInt(brokerListSet.size());
int currentPartitionId = startPartitionId >= 0 ? startPartitionId : 0;
int nextReplicaShift = fixedStartIndex >= 0 ? fixedStartIndex : random.nextInt(brokerListSet.size()); for (int i = 0; i < nPartitions; i++) {
if (currentPartitionId > 0 && ((currentPartitionId % brokerListSet.size()) == 0)) {
nextReplicaShift++;
}
int firstReplicaIndex = (currentPartitionId + startIndex) % brokerListSet.size();
List<Integer> replicaList = new ArrayList<Integer>();
replicaList.add(brokerListSet.get(firstReplicaIndex));
for (int j = 0; j < (nReplicationFactor - 1); j++) {
replicaList.add(brokerListSet.get(getReplicaIndex(firstReplicaIndex, nextReplicaShift, j, brokerListSet.size())));
}
result.put("" + currentPartitionId, getReverseList(replicaList));
currentPartitionId++;
} return result;
} private static List<Integer> getReverseList(List<Integer> list) {
List<Integer> result = new ArrayList<Integer>();
for (int i = list.size() - 1; i >= 0; i--) {
result.add(list.get(i));
}
return result;
} private static int getReplicaIndex(int firstReplicaIndex, int nextReplicaShift, int replicaIndex, int nBrokers) { int shift = 1 + (nextReplicaShift + replicaIndex) % (nBrokers - 1);
int result = (firstReplicaIndex + shift) % nBrokers;
// System.out.println(firstReplicaIndex+"|"+nextReplicaShift+"|"+replicaIndex+"="+result);
return result;
} private static void printAssignReplicas(Map<String, List<Integer>> map, List<Integer> brokerListSet) {
Map<Integer, List<String>> brokerMap = new HashMap<Integer, List<String>>();
for (int i = 0; i < brokerListSet.size(); i++) {
List<String> partitions = new ArrayList<String>();
for (int j = 0; j < map.size(); j++) {
List<Integer> brokerIds = map.get(j + "");
if (brokerIds.contains(i)) {
partitions.add("" + j);
}
}
brokerMap.put(i, partitions);
}
} }

Java curator操作zookeeper获取kafka的更多相关文章

  1. Java代码操作zookeeper

    .personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...

  2. 使用Curator操作ZooKeeper

    Curator是Netflix公司开源的一个ZooKeeper client library,用于简化ZooKeeper客户端编程.它包含如下模块: Framework:Framework是ZooKe ...

  3. 通过Curator操作Zookeeper的简单例子代码

    Curator主要解决了三类问题: 一个是ZooKeeper client与ZooKeeper server之间的连接处理; 一个是提供了一套Fluent风格的操作API; 一个是ZooKeeper各 ...

  4. Java API操作ZooKeeper

    创建会话 package org.zln.zk; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watch ...

  5. curator操作zookeeper

    使用zookeeper原生API实现一些复杂的东西比较麻烦.所以,出现了两款比较好的开源客户端,对zookeeper的原生API进行了包装:zkClient和curator.后者是Netflix出版的 ...

  6. 六、Java API操作zookeeper节点

    目录 前文 pom.xml文件增加依赖 新建java文件:ZookeeperTest GitHub文件下载 前文 一.CentOS7 hadoop3.3.1安装(单机分布式.伪分布式.分布式 二.JA ...

  7. java 正则操作之获取

    // 正则操作 获取import java.util.regex.*;class Demo{ public static void main(String[] args){  String str=& ...

  8. Java简单操作Zookeeper

    Zookeeper客户端链接 <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId ...

  9. JAVA枚举操作(获取值,转map集合)

    JAVA枚举相对来说比.NET的枚举功能强大,感觉就像是一种简化版的类对象,可以有构造方法,可以重载,可以继承接口等等,但不能继承类,JAVA枚举在实际开发中应用相当频繁,以下几个封装方法在实际开发中 ...

随机推荐

  1. [0] 分析 EntityName 时出错。 行 2,位置 *。

    1. 报错内容“若要在加载设计器前避免可能发生的数据丢失,必须纠正以下错误: ”   “分析 EntityName 时出错. 行 2,位置 *.” 2. 如图: 3. 解决方案:查看项目全路径,是否有 ...

  2. 使用 Socket.IO 开发聊天室

    前言 Socket.IO 是一个用来实现实时双向通信的框架,其本质是基于 WebSocket 技术. 我们首先来聊聊 WebSocket 技术,先设想这么一个场景: · 用户小A,打开了某个网站的充值 ...

  3. 搭建phabricator代码审核工具

    phabricator 依赖环境 系统centos,mysql,php,nginx 1.下载安装脚本 https://secure.phabricator.com/source/phabricator ...

  4. 高考志愿填报:java 软件 程序员 目前的就业现状

    大约在17年前,也就是2000年,学计算机专业的学生可以有大部分都进入本专业,并且就业非常容易.哪怕只会office套件,想找个工作也很简单.那时候学计算机就是最热门的行业. 那时候,搞Java的还是 ...

  5. Flash TextField selectable bug block TextEvent.Link solution

    There is an old version Felx SDK bug(in my case it's Flex SDK v3.3.0.4852) that when TextField.selec ...

  6. 实现自己的.NET Core配置Provider之EF

    <10分钟就能学会.NET Core配置>里详细介绍了.NET Core配置的用法,另外我还开源了自定义的配置Provider:EF配置Provider和Yaml配置Provider.本文 ...

  7. mac如何进入应用程序的内部文件夹?

    在程序点击右键,选择显示包内容,就可以看到了

  8. JAVA基础——类和对象

    java类与对象学习笔记 一.成员变量和局部变量 (1)定义 1.成员变量 在类中定义,用来描述对象将要有什么.(默认的成员变量值为0) 2.局部变量 在类的方法中定义,在方法中临时保存数据. 演示示 ...

  9. eclipse 导入git库 Android工程

    1. 导入git库 1.1 从git库 clone 代码 在file->import中选中Git 目录下的Projects from Git 点击Next 选择 URL 点击Next 输入URL ...

  10. web拖动条显示

    <!DOCTYPE html"> <html> <head> <title>滚动条拖动评分的JS效果</title> <st ...