Kafka查看topic中的消息堆积数量
1. 命令行的方式查看消息堆积
kafka-consumer-groups.sh --bootstrap-server ip:port --describe --group YourGroupName
上方结果从左到右依次为:
消费者组-topic-分区-当前消费者消费进度-当前消息总数-消息堆积数(两者差值)-消费者id
2. java代码的方式(通过AdminClient获取)
/**
* 获取主题下的消息堆积量
* @param groupID 消费者组id
* @param topic 主题
*/
public Long lagOf(String groupID, String topic) {
Properties props = new Properties();
//你的服务ip端口
String bootstrapServers = "";
props.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
AdminClient adminClient = AdminClient.create(props);
ListConsumerGroupOffsetsResult result = adminClient.listConsumerGroupOffsets(groupID);
try {
//consumedOffsets消费者组最新消费位移
Map<TopicPartition, OffsetAndMetadata> consumedOffsets = result.partitionsToOffsetAndMetadata().get(10, TimeUnit.SECONDS);
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false); // 禁止自动提交位移
props.put(ConsumerConfig.GROUP_ID_CONFIG, groupID);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
//各分区最新生产消息位移
Map<TopicPartition, Long> endOffsets = consumer.endOffsets(consumedOffsets.keySet());
HashSet<TopicPartition> tempPartitions = new HashSet<>(consumedOffsets.keySet());
//过滤出想要的topic下的所有分区最新消息位移
tempPartitions.forEach(topicPartition -> {
if (!topicPartition.topic().equals(topic)) {
consumedOffsets.remove(topicPartition);
endOffsets.remove(topicPartition);
}
});
//分区最新消息位移-消费者组最新消费位移得到消息堆积数
return endOffsets.entrySet().stream().mapToLong(entry -> entry.getValue() - consumedOffsets.get(entry.getKey()).offset()).sum();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("中断异常,异常信息为:{}", e);
return -1L;
} catch (ExecutionException e) {
log.error("Execution异常,异常信息为:{}", e);
return -1L;
} catch (TimeoutException e) {
log.error("超时异常,异常信息为:{}", e);
return -1L;
}
}
3. 其他方式
也可以使用Zabbix或者Prometheus来监控消息堆积数量,不过我这边使用的业务场景需要在业务代码中去获取,然后根据消息堆积数量的不同做不同的处理,所以不太合适