如何使用Java中的Kafka 8.2 API生成消息?

时间:2015-03-30 18:45:11

标签: java sockets maven apache-kafka

我试图在java中使用kafka API。我使用以下maven依赖:

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>0.8.2.0</version>
</dependency>

我无法连接到远程kafka服务器。 我改变了kafka&#39; server.properties&#39;文件端口属性为端口8080。 我可以启动zookeeper和kafka服务器没问题。 我还可以使用kafka下载附带的控制台生产者和消费者应用程序。 (Scala 2.10版)

我使用以下客户端代码创建远程KafkaProducer

Properties propsProducer = new Properties();

propsProducer.put("bootstrap.servers", "172.xx.xx.xxx:8080");
propsProducer.put("key.serializer", org.apache.kafka.common.serialization.ByteArraySerializer.class);
propsProducer.put("value.serializer", org.apache.kafka.common.serialization.ByteArraySerializer.class);
propsProducer.put("topic.metadata.refresh.interval.ms", "0");

KafkaProducer<byte[], byte[]> m_kafkaProducer = new KafkaProducer<byte[], byte[]>(propsProducer);

一旦我创建了生产者,我就可以运行以下行并返回有效的主题信息,授予strTopic是现有的主题名称。

List<PartitionInfo> partitionInfo = m_kafkaProducer.partitionsFor(strTopic);

当我尝试发送消息时,我会执行以下操作:

ProducerRecord<byte[], byte[]> prMessage = new ProducerRecord<byte[],byte[]>(strTopic, strMessage.getBytes());

RecordMetadata futureData = m_kafkaProducer.send(prMessage).get();

对send()的调用无限期地阻塞,当我手动终止进程时,由于kafka服务器上的错误(IOException,Peer连接重置)错误,我看到ERROR Closing socket。

此外,什么都没有,host.name,advertised.host.name和advertised.port属性仍然在&#39; server.properties&#39;上被注释掉了。文件。哦,如果我换线:

propsProducer.put("bootstrap.servers", "172.xx.xx.xxx:8080");

propsProducer.put("bootstrap.servers", "127.0.0.1:8080");

并在与安装kafka服务器的服务器相同的服务器上运行它,它可以正常工作,但我尝试远程使用它。

感谢任何帮助,如果我能澄清一下,请告诉我。

1 个答案:

答案 0 :(得分:3)

经过大量挖掘后,我决定实施此处的示例:Kafka Producer Example。我缩短了代码并没有实现分区器类。我用列出的依赖项更新了我的pom,但我仍然遇到同样的问题。最终,我做了一些配置更改,一切正常。

最后一个难题是在服务器和客户端计算机的/ etc / hosts中定义Kafka服务器。我在两个文件中添加了以下内容。

172.xx.xx.xxx     serverHost1

同样,x只是面具。然后,我将server.properties文件中的advertised.host.name设置为serverHost1。注意:在服务器计算机上运行ifconfig后,我获得了该IP。

我改变了行

propsProducer.put("metadata.broker.list", "172.xx.xx.xxx:8080");

propsProducer.put("metadata.broker.list", "serverHost1:8080");

Kafka API不喜欢我将IP定义为字符串的事实。相反,它正在etc / hosts文件中查找IP,尽管文档说:

“代理将向生产者和使用者通告的主机名。如果未设置,则使用”host.name“的值(如果已配置)。否则,它将使用从java.net.InetAddress.getCanonicalHostName()返回的值。 “

这将以字符串形式返回IP,如果未在客户端计算机的etc / hosts中定义,则我之前使用,否则返回与IP配对的名称(在我的情况下为serverHost1)。另外,我从未设置过host.name的值。