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. .net 4.0 中的特性总结(二):默认参数、命名参数

    1.在方法定义的时候为参数指定一个默认值.调用方法的时候既可以像平时那样传入参数,也可以直接跳过不传入,这样的话,就使用默认值传到方法里.例如: 2.在之前版本的C#中,方法定义的参数顺序必须与方法调 ...

  2. ecshop开发帮助

    http://www.ecshop.com/template_tutorial/ ECSHOP模板结构说明 http://help.ecshop.com/index.php ECSHOP帮助中心 ht ...

  3. eclispe JavaEE 配置tomcat

    http://blog.csdn.net/hongshan50/article/details/8293526 http://blog.csdn.net/longshengguoji/article/ ...

  4. spingMVC aop不生效的解决方式

    从网上搜索了一些资料,参考了下面的这个解决方案 http://blog.csdn.net/mmm333zzz/article/details/16858209

  5. EL表达式拼接字符串

    EL表达式拼接字符串<c:set var="types" value="${','}${resMap['vo'].lineType }${','}" &g ...

  6. dubbo 请求调用过程分析

    服务消费方发起请求 当服务的消费方引用了某远程服务,服务的应用方在spring的配置实例如下: <dubbo:referenceid="demoService"interfa ...

  7. VMware中Linux系统时间与主机同步以及时区设置

    网络上有各种资料,但最简单的一种方法就是修改虚拟机的配置文件 *.vmx .修改 tools.syncTime = "FALSE" 为 tools.syncTime = " ...

  8. http请求的完整过程

    HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤: 1. 建立TCP连接 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该 ...

  9. TCP/IP三次握手,四次断开

    在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认: SYN: ...

  10. Openfire4源码部署到eclipse中并编译

    Openfire4源码部署到eclipse中并编译 概述 Openfire是众所周知的基于xmpp协议的IM开源服务,所有操作,配置,监控,调试等以B/S方式进行展示,非常的方便管理员进行管理.它的强 ...