使用不正确的凭据进行身份验证时,我在身份验证期间收到了以下预期消息。
[Consumer clientId = consumer-1,groupId = xxx]与节点-1的连接 验证期间终止。这可能表明了这一点 由于凭据无效,身份验证失败。
这一切都很好,但是现在我只能在日志文件中找到这些信息,而我想对这条消息采取行动。
我还查看了此消息源自的Kafka源代码:
(在1.1中)https://github.com/apache/kafka/blob/1.1/clients/src/main/java/org/apache/kafka/clients/NetworkClient.java (或在主干中)https://github.com/apache/kafka/blob/trunk/clients/src/main/java/org/apache/kafka/clients/NetworkClient.java)
有一些像这样的代码:
switch (disconnectState.state()) {
case AUTHENTICATION_FAILED:
connectionStates.authenticationFailed(nodeId, now, disconnectState.exception());
log.error("Connection to node {} failed authentication due to: {}", nodeId, disconnectState.exception().getMessage());
break;
case AUTHENTICATE:
// This warning applies to older brokers which dont provide feedback on authentication failures
log.warn("Connection to node {} terminated during authentication. This may indicate " +
"that authentication failed due to invalid credentials.", nodeId);
break;
重要提示:我使用基于SASL_PLAIN的自定义模块覆盖Kafka中的身份验证机制,而我刚刚调试时,我在身份验证期间意识到此模块中出现了其他问题,导致了与此不同的异常模块,这意味着它触发了这个老年经纪人'代码路径。但是,我仍然希望对这个州采取一些行动。
我尝试过创建一个监听器,如下所示:
final ContainerProperties containerProperties = new ContainerProperties("TEST_TOPIC");
containerProperties.setAckMode(AbstractMessageListenerContainer.AckMode.MANUAL_IMMEDIATE);
containerProperties.setMessageListener((AcknowledgingMessageListener<GenericRecord, GenericRecord>) (record, ack) -> logger.info("Got record on test topic"));
KafkaMessageListenerContainer<GenericRecord, GenericRecord> container = new KafkaMessageListenerContainer<>(kafkaConsumerFactory, containerProperties);
container.start();
但代码不会抛出任何身份验证异常,它只是在日志中继续打印上述消息。
我也尝试过创建一个简单的消费者,如下所示:
Consumer<GenericRecord, GenericRecord> consumer = kafkaConsumerFactory.createConsumer();
consumer.subscribe(Collections.singleton("BX_TEST_TOPIC"));
try {
ConsumerRecords<GenericRecord, GenericRecord> poll = consumer.poll(10);
}
catch (Exception e) {
logger.info("Exception during polling", e);
}
但是这段代码也没有抛出任何异常,它也只是在日志中继续打印消息。即使根据https://kafka.apache.org/10/javadoc/org/apache/kafka/clients/consumer/KafkaConsumer.html#poll-long-,poll方法可能会抛出AuthenticationException。这可能是因为年龄较大的经纪人&#39;消息类型,在源代码中仅在日志中显示警告。
那么,如果服务器没有返回认证异常但仍然无法登录,如何实际捕获任何AuthenticationException或以某种有意义的方式获取连接状态而不是解析日志?
请注意,当身份验证不是问题时会发生完全相同的问题,但其他问题会失败。例如,有时我的Kafka集群没有正确启动,在这种情况下,我收到此消息:
无法建立与节点-1的连接。经纪人可能不会 可用。
我也无法检查。相反,当客户端进入无限循环尝试连接时,日志会不断填写此消息。
答案 0 :(得分:1)
您可以通过增加重试退避来减少循环。
您可以使用类似......
之类的内容来检查经纪人的状态spring.kafka.producer.properties.retry.backoff.ms=1000
spring.kafka.producer.properties.max.block.ms=10000
spring.kafka.bootstrap-servers=localhost:9096
和
@Bean
public ApplicationRunner runner(ProducerFactory<?, ?> producerFactory) {
return args -> {
try (Producer<?, ?> producer = producerFactory.createProducer()) {
producer.partitionsFor("foo");
}
catch (Exception e) {
e.printStackTrace();
}
};
}
和
org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 10000 ms.
我缩小了max.block.ms
,因为它默认为60秒。