一、问题描述

使用的代码如下,出现问题后使用kafka-consumer-groups.sh脚本查看,发现consumer-id,host,client-id均为空,这是很不正常的,于是搜索相关,在这篇博客找到了原因,()

@KafkaListener(topicPartitions = {@TopicPartition(topic = "arch",partitions = {"0"})})

kafka yml用户名密码 kafka client id_学习

二、问题解决

之所以出现上面的的问题,是因为使用了消费组的手动分区,也就是consumer.assign()方式,如果使用了手动分区,则分区的自动管理方式不会再起作用,而且如果消费组成员变更或主题的元数据等信息改变,将不会触发再平衡机制。

kafka yml用户名密码 kafka client id_面试_02


结论

  KafkaConsumer.subscribe() : 为consumer自动分配partition,有内部算法保证topic-partition以最优的方式均匀分配给同group下的不同consumer。

  KafkaConsumer.assign() : 为consumer手动、显示的指定需要消费的topic-partitions,不受group.id限制,相当与指定的group无效(this method does not use the consumer’s group management)。

二、验证

两个服务节点,各自启动三个消费者

kafka yml用户名密码 kafka client id_学习_03


kafka yml用户名密码 kafka client id_大数据_04


一个服务节点,启动三个消费者,concurrency设置为3,所以实际上是9个

kafka yml用户名密码 kafka client id_学习_05

结论

client-id并不能唯一标识一个消费者,如果启动两个服务节点,就有重复的client-id出现,真正确定一个消费者的是consumer-id,由client-id+随机数生成
至于client-id的作用,官方给出的描述如下

An id string to pass to the server when making requests. The purpose of this is to be able to track the source of requests beyond just ip/port by allowing a logical application name to be included in server-side request logging.

发出请求时要传递给服务器的id字符串。这样做的目的是通过允许在服务器端请求日志中包含逻辑应用程序名称,能够跟踪不仅仅是ip/端口的请求源。

kafka yml用户名密码 kafka client id_面试_06

查看kafka的server.log文件发现确实是在日志中起到标识作用的实际上是consumer-id,而并不是client-id,而client-id相当于只是consumer-id的一部分,但是由于consumer-id对使用者来说是不可见的,用户能够配置的只是consumer-id的前缀,即client-id,所以官方的解释本质上来说并没有太大问题