[英]Apache Kafka create topic from code
我们知道Kafka中的Topic
创建应该在服务器初始化部分进行处理。 我们使用默认脚本./kafka-topics --zookeeper ...
,但是如果我们需要动态创建主题呢?
幸运的是, Kafka 0.10.1.0
为我们带来了这种能力。 我在Confluence Jira板上看到了这些引人入胜的功能,但找不到与该主题相关的任何文档,具有讽刺意味,不是吗?
所以,我去了源代码,找到了动态创建主题的方法。 希望它对你们中的一些人有所帮助。 当然,如果您有更好的解决方案,请不要犹豫与我们分享。
好的,我们开始吧。
/** The method propagate topics **/
public List<String> propagateTopics(int partitions, short replication, int timeout) throws IOException {
CreateTopicsRequest.TopicDetails topicDetails = new CreateTopicsRequest.TopicDetails(partitions, replication);
Map<String, CreateTopicsRequest.TopicDetails> topicConfig = mTopics.stream()
.collect(Collectors.toMap(k -> k, v -> topicDetails)); // 1
CreateTopicsRequest request = new CreateTopicsRequest(topicConfig, timeout); // 2
try {
CreateTopicsResponse response = createTopic(request, BOOTSTRAP_SERVERS_CONFIG); // 3
return response.errors().entrySet().stream()
.filter(error -> error.getValue() == Errors.NONE)
.map(Map.Entry::getKey)
.collect(Collectors.toList()); // 4
} catch (IOException e) {
log.error(e);
}
return null;
}
1
我们需要一个TopicDetails
实例,为简单起见,我将在所有主题中共享相同的配置。 假设mTopics
是您要创建的所有主题的字符串列表。
2
基本上我们想要向我们的Kafka集群发送请求,现在我们有了特殊的类, - 接受CreateTopicsRequest
和timeout
3
我们需要发送请求并获取CreateTopicsResponse
private static final short apiKey = ApiKeys.CREATE_TOPICS.id;
private static final short version = 0;
private static final short correlationId = -1;
private static CreateTopicsResponse createTopic(CreateTopicsRequest request, String client) throws IllegalArgumentException, IOException {
String[] comp = client.split(":");
if (comp.length != 2) {
throw new IllegalArgumentException("Wrong client directive");
}
String address = comp[0];
int port = Integer.parseInt(comp[1]);
RequestHeader header = new RequestHeader(apiKey, version, client, correlationId);
ByteBuffer buffer = ByteBuffer.allocate(header.sizeOf() + request.sizeOf());
header.writeTo(buffer);
request.writeTo(buffer);
byte byteBuf[] = buffer.array();
byte[] resp = requestAndReceive(byteBuf, address, port);
ByteBuffer respBuffer = ByteBuffer.wrap(resp);
ResponseHeader.parse(respBuffer);
return CreateTopicsResponse.parse(respBuffer);
}
private static byte[] requestAndReceive(byte[] buffer, String address, int port) throws IOException {
try(Socket socket = new Socket(address, port);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
DataInputStream dis = new DataInputStream(socket.getInputStream())
) {
dos.writeInt(buffer.length);
dos.write(buffer);
dos.flush();
byte resp[] = new byte[dis.readInt()];
dis.readFully(resp);
return resp;
} catch (IOException e) {
log.error(e);
}
return new byte[0];
}
这根本不是魔术,只是发送请求,而不是将字节流解析为响应。
4
CreateTopicsResponse
有属性errors
,它只是Map<String, Errors>
,其中key
是您请求的主题名称。 棘手的是,它包含您请求的所有主题,但没有错误的主题具有值Errors.None
,这就是我过滤响应并仅返回成功创建的主题的原因。
延伸Andrei Nechaev的答案
在10.2.0中,获取CreateTopicsRequest实例的方式有所改变。 我们需要使用Builder内部类来构建CreateTopicsRequest实例。 这是一个代码示例。
CreateTopicsRequest.Builder builder = new CreateTopicsRequest.Builder(topicConfig, timeout, false);
CreateTopicsRequest request = builder.build();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.