简体   繁体   English

如何摆脱“使用 timeoutMillis = ... 关闭 Kafka 生产者”

[英]How to get rid of “Closing the Kafka producer with timeoutMillis = …”

I am sending Apache Avro formatted messages to a Kafka broker instance via the following code:我通过以下代码向 Kafka 代理实例发送 Apache Avro 格式的消息:

        ProducerRecord<String, byte[]> producerRecord = new ProducerRecord<>(kafkaTopic.getTopicName(), null, null,
                avroConverter.getSchemaId().toString(), convertRecordToByteArray(kafkaRecordToSend));

        String avroSchemaName = null;

        // some of my AVRO schemas are unions, some are simple:
        if (_avroSchema.getTypes().size() == 1) {
            avroSchemaName = _avroSchema.getTypes().get(0).getName();
        } else if (_avroSchema.getTypes().size() == 2) {
            avroSchemaName = _avroSchema.getTypes().get(1).getName();
        }

        // some custom header items...
        producerRecord.headers().add(MessageHeaders.MESSAGE_ID.getText(), messageID.getBytes());
        producerRecord.headers().add(MessageHeaders.AVRO_SCHEMA_REGISTRY_SUBJECT.getText(),
                avroSchemaName.getBytes());
        producerRecord.headers().add(MessageHeaders.AVRO_SCHEMA_REGISTRY_SCHEMA_ID.getText(),
                avroConverter.getSchemaId().toString().getBytes());
        if (multiline) {
            producerRecord.headers().add(MessageHeaders.AVRO_SCHEMA_MULTILINE_RECORD_NAME.getText(),
                    MULTILINE_RECORD_NAME.getBytes());
        }

        try {
            Future<RecordMetadata> result = kafkaProducer.send(producerRecord);
            RecordMetadata sendResult = result.get();
            MessageLogger.logResourceBundleMessage(_messages, "JAPCTOAVROKAFKAPRODUCER:DEBUG0002",
                    sendResult.offset());
        } catch (Exception e) {
            MessageLogger.logError(e);
            throw e;
        }

The code works fine, the messages end up in Kafka and are processed to end up in an InfluxDB.代码工作正常,消息最终在 Kafka 中并经过处理最终在 InfluxDB 中。 The problem is that every send operation produces a lot of INFO messages (client ID number is an example):问题是每个发送操作都会产生大量的 INFO 消息(客户端 ID 号就是一个例子):

  • [Producer clientId=producer-27902] Closing the Kafka producer with timeoutMillis = 10000 ms. [Producer clientId=producer-27902] 使用 timeoutMillis = 10000 ms 关闭 Kafka 生产者。
  • [Producer clientId=producer-27902] Closing the Kafka producer with timeoutMillis = 9223372036854775807 ms. [Producer clientId=producer-27902] 使用 timeoutMillis = 9223372036854775807 ms 关闭 Kafka 生产者。
  • Kafka startTimeMs: ...卡夫卡开始时间:...
  • Kafka commitId: ...卡夫卡提交ID:...
  • [Producer clientId=producer-27902] Cluster ID: [生产者 clientId=producer-27902] 集群 ID:

which Spam our Graylog.哪个垃圾邮件我们的 Graylog。

I use similar code to send String formatted messages.我使用类似的代码来发送字符串格式的消息。 This code is executed without producing INFO messages...执行此代码时不会产生 INFO 消息...

ProducerRecord<String, String> recordToSend = new ProducerRecord<>(queueName, messageText);
    recordToSend.headers().add("messageID", messageID.getBytes());

    Future<RecordMetadata> result = _producerConnection.send(recordToSend);
    

I know that the INFO message are logged from class org.apache.kafka.clients.producer.KafkaProducer .我知道 INFO 消息是从 class org.apache.kafka.clients.producer.KafkaProducer记录的。 I need to get rid of these messages, but I do not have access to the logging.mxl defining the logger properties for Graylog.我需要摆脱这些消息,但我无权访问为 Graylog 定义记录器属性的 logging.mxl。

Is there a way to get rid of these messages via POM-entries or programatically?有没有办法通过 POM 条目或以编程方式摆脱这些消息?

The reason of the code behavior was a design flaw: The code in the post above was placed in a method which was called for sending the message to Kafka.代码行为的原因是一个设计缺陷:上面帖子中的代码被放置在一个方法中,该方法被调用用于向 Kafka 发送消息。 The KafkaProducer class was instantiated in that method and each time when the method was called. KafkaProducer class 在该方法中以及每次调用该方法时都被实例化。 Surprisingly, KafkaProducer issues the Closing the KafkaProducer with timeoutMillis = not only at an explicit close() by the calling code, but as well when the strong reference to the instance is lost ( in my case when the code leaves the method), In the latter case, the timeoutMillis is set to 9223372036854775807 (largest long number).令人惊讶的是, KafkaProducer不仅在调用代码的显式 close() 时发出Closing the KafkaProducer with timeoutMillis = ,而且在对实例的强引用丢失时(在我的情况下,当代码离开方法时),在后一种情况, timeoutMillis设置为 9223372036854775807(最大长数)。

To get rid of the many messages, I moved the KafkaProducer instantiation out of the method and made the instance variable a class attribute and I do not call an explicit close() after the send(...) any more.为了摆脱许多消息,我将KafkaProducer实例化移出方法并将实例变量设为 class 属性,并且我不再在send(...)之后调用显式close()

Furthermore I changed the instance of my class instantiating KafkaProducer to a strong referencing class member.此外,我将实例化KafkaProducer的 class 的实例更改为强引用 class 成员。

By doing so, I get some messages by the KafkaProducer at instantiation, then there is silence.通过这样做,我在实例化时收到了KafkaProducer的一些消息,然后是静默。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM