Kafka查看topic中的消息堆积数量

1,312 阅读1分钟

Kafka查看topic中的消息堆积数量

1. 命令行的方式查看消息堆积

kafka-consumer-groups.sh --bootstrap-server ip:port --describe --group YourGroupName

image.png 上方结果从左到右依次为:

消费者组-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来监控消息堆积数量,不过我这边使用的业务场景需要在业务代码中去获取,然后根据消息堆积数量的不同做不同的处理,所以不太合适