Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache kafka 卡夫卡:使用主题中的第一条消息时间歇性缓慢_Apache Kafka - Fatal编程技术网

Apache kafka 卡夫卡:使用主题中的第一条消息时间歇性缓慢

Apache kafka 卡夫卡:使用主题中的第一条消息时间歇性缓慢,apache-kafka,Apache Kafka,我使用的是卡夫卡0.9.0.1 第一次启动应用程序时,从主题中检索“最新”消息需要20-30秒 我使用了不同的Kafka代理(配置不同),但我仍然看到这种行为。后续消息通常不慢 这是预期的行为吗?通过运行此示例应用程序并将代理/主题名称更改为您自己的设置,您可以在下面清楚地看到这一点 public class KafkaProducerConsumerTest { public static final String KAFKA_BROKERS = "..."; public

我使用的是卡夫卡0.9.0.1

第一次启动应用程序时,从主题中检索“最新”消息需要20-30秒

我使用了不同的Kafka代理(配置不同),但我仍然看到这种行为。后续消息通常不慢

这是预期的行为吗?通过运行此示例应用程序并将代理/主题名称更改为您自己的设置,您可以在下面清楚地看到这一点

public class KafkaProducerConsumerTest {

    public static final String KAFKA_BROKERS = "...";
    public static final String TOPIC = "...";

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        new KafkaProducerConsumerTest().run();
    }

    public void run() throws ExecutionException, InterruptedException {
        Properties consumerProperties = new Properties();
        consumerProperties.setProperty("bootstrap.servers", KAFKA_BROKERS);
        consumerProperties.setProperty("group.id", "Test");
        consumerProperties.setProperty("auto.offset.reset", "latest");
        consumerProperties.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        consumerProperties.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        MyKafkaConsumer kafkaConsumer = new MyKafkaConsumer(consumerProperties, TOPIC);
        Executors.newFixedThreadPool(1).submit(() -> kafkaConsumer.consume());

        Properties producerProperties = new Properties();
        producerProperties.setProperty("bootstrap.servers", KAFKA_BROKERS);
        producerProperties.setProperty("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        producerProperties.setProperty("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        MyKafkaProducer kafkaProducer = new MyKafkaProducer(producerProperties, TOPIC);
        kafkaProducer.publish("Test Message");
    }
}


class MyKafkaConsumer {
    private final Logger logger = LoggerFactory.getLogger(MyKafkaConsumer.class);
    private KafkaConsumer<String, Object> kafkaConsumer;

    public MyKafkaConsumer(Properties properties, String topic) {
        kafkaConsumer = new KafkaConsumer<String, Object>(properties);
        kafkaConsumer.subscribe(Lists.newArrayList(topic));
    }

    public void consume() {
        while (true) {
            logger.info("Started listening...");
            ConsumerRecords<String, Object> consumerRecords = kafkaConsumer.poll(Long.MAX_VALUE);
            logger.info("Received records {}", consumerRecords.iterator().next().value());
        }
    }
}

class MyKafkaProducer {
    private KafkaProducer<String, Object> kafkaProducer;
    private String topic;

    public MyKafkaProducer(Properties properties, String topic) {
        this.kafkaProducer = new KafkaProducer<String, Object>(properties);
        this.topic = topic;
    }

    public void publish(Object object) throws ExecutionException, InterruptedException {
        ProducerRecord<String, Object> producerRecord = new ProducerRecord<>(topic, "key", object);
        Future<RecordMetadata> response = kafkaProducer.send(producerRecord);
        response.get();
    }

}
KafkaProducerConsumerTest公共类{
公共静态最终字符串KAFKA_=“…”;
公共静态最终字符串主题=“…”;
公共静态void main(字符串[]args)引发ExecutionException、InterruptedException{
新的KafkaProducerConsumerTest().run();
}
public void run()引发ExecutionException、InterruptedException{
Properties consumerProperties=新属性();
consumerProperties.setProperty(“bootstrap.servers”,KAFKA_BROKERS);
consumerProperties.setProperty(“group.id”、“Test”);
consumerProperties.setProperty(“auto.offset.reset”、“latest”);
setProperties(“value.deserializer”、“org.apache.kafka.common.serialization.StringDeserializer”);
setProperties(“key.deserializer”、“org.apache.kafka.common.serialization.StringDeserializer”);
MYKAFKCONSUMER KAFKCONSUMER=新的MYKAFKCONSUMER(消费者财产,主题);
Executors.newFixedThreadPool(1).submit(()->kafkaConsumer.consumer());
Properties producerProperties=新属性();
producerProperties.setProperty(“bootstrap.servers”,KAFKA_BROKERS);
setProperties(“value.serializer”、“org.apache.kafka.common.serialization.StringSerializer”);
setProperties(“key.serializer”、“org.apache.kafka.common.serialization.StringSerializer”);
MyKafkaProducer kafkaProducer=新的MyKafkaProducer(产品属性,主题);
kafkaProducer.publish(“测试消息”);
}
}
MyKafkaConsumer类{
私有最终记录器Logger=LoggerFactory.getLogger(MyKafkaConsumer.class);
私人卡夫卡消费者卡夫卡消费者;
公共MyKafkaConsumer(属性,字符串主题){
卡夫卡消费者=新卡夫卡消费者(财产);
kafkaConsumer.subscribe(list.newArrayList(topic));
}
公共消费(){
while(true){
logger.info(“开始侦听…”);
ConsumerRecords ConsumerRecords=kafkaConsumer.poll(Long.MAX_值);
info(“已接收记录{}”,consumerRecords.iterator().next().value());
}
}
}
类MyKafkaProducer{
私人卡夫卡制作人卡夫卡制作人;
私有字符串主题;
公共MyKafkaProducer(属性,字符串主题){
this.kafkaProducer=新的kafkaProducer(属性);
this.topic=主题;
}
public void publish(对象对象)引发ExecutionException、InterruptedException{
ProducerRecord ProducerRecord=新的ProducerRecord(主题,“键”,对象);
未来响应=kafkaProducer.send(producerRecord);
response.get();
}
}

第一条消息应该比其他消息花费更长的时间,因为当您在语句
consumerProperties.setProperty(“group.id”,“Test”)指定的消费者组中启动新消费者时,Kakfka将平衡分区,使每个分区由一个使用者使用,并将主题的分区分布在多个使用者进程中

此外,在Kafka 0.9中,还有一个单独的
\uu consumer\u offset
主题,Kafka使用该主题来管理消费者组中每个消费者的偏移量。很可能当您第一次启动使用者时,它会查看此主题以获取最新的偏移量(先前可能有一个使用者正在使用此主题中的偏移量,该偏移量可能会被杀死,因此有必要从正确的偏移量获取)

这两个因素将导致第一组消息的使用延迟更高。我不能评论20-30秒的确切延迟,但我想这应该是默认行为


PS:确切的数字还可能取决于其他次要因素,如您是在同一台机器上运行代理和消费者(没有网络延迟),还是在不同的机器上运行,他们将使用TCP进行通信。

现在多次尝试您的代码,但添加的日志记录很少。以下是典型的日志输出:

2016-07-24 15:12:51,417 Start polling...|INFO|KafkaProducerConsumerTest
2016-07-24 15:12:51,604 producer has send message|INFO|KafkaProducerConsumerTest
2016-07-24 15:12:51,619 producer got response, exiting|INFO|KafkaProducerConsumerTest
2016-07-24 15:12:51,679 Received records [Test Message]|INFO|KafkaProducerConsumerTest
2016-07-24 15:12:51,679 Start polling...|INFO|KafkaProducerConsumerTest
2016-07-24 15:12:54,680 returning on empty poll result|INFO|KafkaProducerConsumerTest
事件的顺序如预期的那样及时。消费者开始轮询,生产者发送消息并接收结果,消费者接收消息,所有这些都需要300毫秒。然后消费者再次开始轮询,并在3秒钟后,当我分别更改轮询超时时抛出

我正在使用Kafka 0.9.0.1作为代理和客户端库。该连接位于localhost上,是一个完全没有负载的测试环境

为完整起见,以下是由上述exchange触发的服务器日志表单

[2016-07-24 15:12:51,599] INFO [GroupCoordinator 0]: Preparing to restabilize group Test with old generation 0 (kafka.coordinator.GroupCoordinator)
[2016-07-24 15:12:51,599] INFO [GroupCoordinator 0]: Stabilized group Test generation 1 (kafka.coordinator.GroupCoordinator)
[2016-07-24 15:12:51,617] INFO [GroupCoordinator 0]: Assignment received from leader for group Test for generation 1 (kafka.coordinator.GroupCoordinator)
[2016-07-24 15:13:24,635] INFO [GroupCoordinator 0]: Preparing to restabilize group Test with old generation 1 (kafka.coordinator.GroupCoordinator)
[2016-07-24 15:13:24,637] INFO [GroupCoordinator 0]: Group Test generation 1 is dead and removed (kafka.coordinator.GroupCoordinator)
您可能希望与同一exchange的服务器日志进行比较。

根据:

尝试在消费者中设置
group\u id=None
,或调用consumer.close() 在结束脚本之前,或使用assign()not subscribe()。否则你就是 重新加入已有已知但无响应成员的现有组。这个 组协调员将等待,直到这些成员签入/离开/超时。 由于使用者不再存在(这是您以前的脚本运行),因此它们已经存在 暂停。 和consumer.poll()在组重新平衡期间阻塞

所以,如果您加入了一个成员无响应的组(可能是您不恰当地终止了应用程序),这是正确的行为

请确认在退出应用程序之前调用“consumer.close()”。

T