谢邀
不过你真的要使用java api来读取__consumer_offsets的内容吗? 实现起来确实有点麻烦,且所用API都是没有官方记录的,后续是否能这样用不敢保证。
不管怎么样,依然给你写了一份,你参考下吧(代码需要引入kafka-core的依赖)
Class klass = Class.forName("kafka.coordinator.group.GroupMetadataManager$OffsetsMessageFormatter");
GroupMetadataManager.OffsetsMessageFormatter formatter = (GroupMetadataManager.OffsetsMessageFormatter) klass.newInstance();
String topic = "__consumer_offsets";
String groupID = "console-consumer-28354"; // 换成你的group ID int leader = Math.abs(groupID.hashCode()) % 50;
SimpleConsumer consumer = new SimpleConsumer("localhost", 9092, 30000, 30000, "test");
FetchRequest request = new FetchRequestBuilder()
.addFetch(topic, leader, 0, 1024 * 1024).build();
FetchResponse resp = consumer.fetch(request);
ByteBufferMessageSet messages = resp.messageSet(topic, leader);
Iterator iter = messages.iterator();
while (iter.hasNext()) {
MessageAndOffset messageAndOffset = iter.next();
Message message = messageAndOffset.message();
byte[] key = message.hasKey() ? Utils.readBytes(message.key()) : null;
byte[] value = message.isNull() ? null : Utils.readBytes(message.payload());
int serializedKeySize = message.hasKey() ? key.length : -1;
int serializedValueSize = message.isNull() ? -1 : value.length;
ConsumerRecord record = new ConsumerRecord<>(
topic, leader, 0, message.timestamp(),
message.timestampType(), message.checksum(), serializedKeySize, serializedValueSize, key, value);
formatter.writeTo(record, System.out);
}
consumer.close();
这段代码的缺陷在于:
1. SimpleConsumer及其他一众“党羽”(比如FetchRequestBuilder等)都已经被标记为“过时”了,而且很有可能下个版本就删除了
2. 在创建SimpleConsumer时硬编码了localhost:9092。真正使用时你需要首先获取group对应的__consumer_offsets分区号,然后自行去寻找这个分区的leader所在的broker主机名和端口。我实在懒得写findLeaderBroker了,你可以参考下https://cwiki.apache.org/confluence/display/KAFKA/0.8.0+SimpleConsumer+Example中的findLeader方法
3. 这段代码从头消费,并且只消费一次就退出了。你需要改成循环读取
4. 如果引入的依赖版本<1.0.0,那么类全限定名换成kafka.coordinator.GroupMetadataManager$OffsetsMessageFormatter
5. __consumer_offsets虽然默认是50个分区,但实际上可以通过offsets.topic.num.partitions来修改。同理,我懒得去用代码获取这个值了,好在一般也不修改此参数。
再次声明:这段代码在未来版本中(>1.0.0)有很大的风险不可用。最好还是通过官方提供的工具来实现此功能。