Java 如果消息是由生产者生成的,如何从Kafka代理获得确认?

Java 如果消息是由生产者生成的,如何从Kafka代理获得确认?,java,apache-kafka,kafka-consumer-api,kafka-producer-api,Java,Apache Kafka,Kafka Consumer Api,Kafka Producer Api,我希望在生成消息时得到代理的一些响应。 我尝试了KafkaProducer.send中使用的回调机制(通过实现回调),但它不起作用,也不调用onCompletion方法当我关闭Kafka服务器并尝试生成消息时,它会调用回调方法 有没有其他方法得到确认 @Override public void onCompletion(RecordMetadata metadata, Exception exception) { long elapsedTime = System.cur

我希望在生成消息时得到代理的一些响应。 我尝试了
KafkaProducer.send
中使用的回调机制(通过实现回调),但它不起作用,也不调用
onCompletion
方法

当我关闭Kafka服务器并尝试生成消息时,它会调用回调方法

有没有其他方法得到确认

@Override
    public void onCompletion(RecordMetadata metadata, Exception exception) {
        long elapsedTime = System.currentTimeMillis() - startTime;
        System.out.println("Called Callback method");
        if (metadata != null) {
            System.out.println("message(" + key + ", " + message
                    + ") sent to partition(" + metadata.partition() + "), "
                    + "offset(" + metadata.offset() + ") in " + elapsedTime
                    + " ms");
        } else {
            exception.printStackTrace();
        }

    }

props.put("bootstrap.servers", "localhost:9092");
props.put("client.id", "mytopic");
props.put("key.serializer", org.apache.kafka.common.serialization.StringSerializer.class);
props.put("value.serializer", org.apache.kafka.common.serialization.ByteArraySerializer.class);

KafkaProducer<String, byte[]> producer = new KafkaProducer<String,byte[]>(props);
long runtime = new Date().getTime(); 
String ip = "192.168.2."+ rnd.nextInt(255); 
String msg = runtime + ".www.ppop.com," + ip;
producer.send(new ProducerRecord<String, byte[]>("mytopic", msg.getBytes()), `new TransCallBack(Calendar.getInstance().getTimeInMillis(), key, msg));`
@覆盖
公共void onCompletion(记录元数据、异常){
long elapsedTime=System.currentTimeMillis()-startTime;
System.out.println(“调用回调方法”);
if(元数据!=null){
System.out.println(“消息(“+key+”,“+message
+)发送到分区(“+metadata.partition()+”)
+“+elapsedTime”中的偏移量(“+metadata.offset()+”)
+“ms”);
}否则{
异常。printStackTrace();
}
}
put(“bootstrap.servers”,“localhost:9092”);
props.put(“client.id”、“mytopic”);
put(“key.serializer”,org.apache.kafka.common.serialization.StringSerializer.class);
put(“value.serializer”,org.apache.kafka.common.serialization.ByteArraySerializer.class);
卡夫卡制作人=新卡夫卡制作人(道具);
long runtime=new Date().getTime();
字符串ip=“192.168.2.”+rnd.nextInt(255);
字符串msg=runtime+”.www.ppop.com,“+ip;
send(newproducerrecord(“mytopic”,msg.getBytes()),`newtranscallback(Calendar.getInstance().getTimeInMillis(),key,msg))`

我将kafka客户端api 0.9.1与代理版本0.8.2一起使用。

因此我不能100%确定在kafka中哪些版本可以使用。目前我使用的是0.8.2,我知道0.9引入了一些突破性的更改,但我无法确定现在哪些是有效的/无效的

一个非常强烈的建议是,我将使用与您的代理版本相对应的Kafka客户端版本。如果您使用的是broker 0.8.2,我也会使用kakfa客户端0.8.2

你从来没有给出过你如何使用它的任何代码,所以我只是在暗中猜测。但是我已经在Kafka 0.8.2中通过在producer中使用实现了回调功能。下面是方法签名

public java.util.concurrent.Future<RecordMetadata> send(ProducerRecord<K,V> record, Callback callback)
public java.util.concurrent.Future发送(ProducerRecord记录,回调)
我将在哪里调用该方法,我实际上是在类中传递被重写的方法

KafkaProducer<String, String> prod = new KafkaProducer<String, String>(props);
ProducerRecord<String, String> record = //data to send to kafka
prod.send(record, new Callback() {
  @Override
  public void onCompletion(RecordMetadata metadata, Exception e) {
    if (e != null) {
      e.printStackTrace();
    } else {
      //implement logic here, or call another method to process metadata
      System.out.println("Callback");
    }
  }
}); 
KafkaProducer prod=新的KafkaProducer(道具);
ProducerRecord=//要发送给卡夫卡的数据
prod.send(记录,新回调(){
@凌驾
公共void onCompletion(RecordMetadata元数据,异常e){
如果(e!=null){
e、 printStackTrace();
}否则{
//在这里实现逻辑,或者调用另一个方法来处理元数据
System.out.println(“回调”);
}
}
}); 

我假设有一种方法也能像你那样做。但你必须提供代码,显示你是如何向卡夫卡发送记录的。除此之外,我只是在猜测

在KafkaProducer使用kafka 0.9版本发布消息后,有一种简单的方法可以从代理获取信息。您可以调用get()方法,该方法将返回RecordMetadata对象,您可以从代码段下面获取诸如偏移量、topicPartition之类的信息,例如:

RecordMetadata m = kafkaProducer.send(new ProducerRecord<byte[], byte[]>(
                        topic, key.getBytes("UTF-8"), message
                                .getBytes("UTF-8"))).get();
System.out.println("Message produced, offset: " + m.offset());
System.out.println("Message produced, partition : " + m.partition());
System.out.println("Message produced, topic: " + m.topic());
RecordMetadata m=kafkaProducer.send(新产品记录(
主题,key.getBytes(“UTF-8”),消息
.getBytes(“UTF-8”)).get();
System.out.println(“生成的消息,偏移量:+m.offset());
System.out.println(“生成的消息,分区:+m.partition());
System.out.println(“生成的消息,主题:+m.topic());
发布完所有消息后,关闭制作人,如下所示:

producer.close();
这可确保始终调用回调中的以下方法:

onCompletion(RecordMetadata metadata, Exception exception)

注意:我已经通过将该行添加到中对此进行了测试,它可以正常工作。

能否显示用于实现回调的代码。如果没有调用此方法,那么问题一定在其他地方。我刚刚将我的代理更新为0.9.0.0,它开始工作。现在的问题是,新的api会不会在0.8.2.x版本上调用回调?请看我的答案,但请再说一遍。向我们展示您用于向卡夫卡发送数据的代码,这可能是您问题的根源。也不建议使用不同的卡夫卡版本。org.apache.Kafka.clients.producer.KafkaProducer producer=new org.apache.Kafka.clients.producer.KafkaProducer(props);long runtime=new Date().getTime();字符串ip=“192.168.2.”+rnd.nextInt(255);字符串msg=runtime+”.www.ppop.com,“+ip;//KeyedMessage数据=新的KeyedMessage(“test”,ip,msg.getBytes());send(newproducerrecord(“mytopic”,msg.getBytes()),newtranscallback(Calendar.getInstance().getTimeInMillis(),key,msg));看起来不错。您是否尝试过将Kafka客户端0.8.2与Broker 0.8.2一起使用?如果您没有传入
TransCallBack
类,而是像我在示例中所做的那样创建一个新的“回调”,会怎么样?