我的家庭网络上的计算机上运行着一个Kafka经纪人。当我将Java生产者(在另一台计算机上)从同一wifi网络连接到该代理时,它绝对可以正常工作,并且能够发布消息而没有任何问题。
作为我应用程序的下一步,我已经通过互联网公开了我的计算机和Kafka的9092端口。我还为该端口打开了系统上的所有防火墙。当我从任何其他网络进行telnet / nc连接尝试时,它都连接良好。 Kafka主机还显示netstat输出中建立的连接。
telnet DNSHOSTNAME 9092
Trying MYIP...
Connected to DNSHOSTNAME.
Escape character is '^]'.
但是从这个外部网络,当我使用完全相同的kafka java生产者从这个外部网络发送到我的家用计算机时,它总是失败并出现以下错误。在与此相关的Kafka日志中,我也没有看到任何连接尝试或错误。
Error while producing message to topic :TP1-0@-1
org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) for TP1-0: 30005 ms has passed since batch creation plus linger time
另一个有趣的一点是,我还有其他应用程序-RabbitMQ和Tomcat与Kafka在同一台计算机上,具有相同的防火墙和路由器规则。我的同一个Java应用程序能够通过Internet连接通过TCP和HTTP发布给他们。只有卡夫卡不起作用。
假设telnet和nc连接连接良好,我认为这不是防火墙或网络路由问题。剩下的仅是生产者代码,如下所示。是否可以在Kafka Broker或Kafka Producer端应用某种类型的设置,以便他们能够通过Internet连接?消费者代码存在相同问题。无法从互联网连接。
生产者代码:
public static void main(String[] args){
Properties props = new Properties();
//props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "DNSHOSTNAME:9092");
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "MYEXTERNALIP:9092");
props.put(ProducerConfig.ACKS_CONFIG, "all");
props.put(ProducerConfig.RETRIES_CONFIG, 0);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new KafkaProducer<String, String>(props);
TestCallback callback = new TestCallback();
Random rnd = new Random();
ProducerRecord<String, String> data = new ProducerRecord<String, String>("TP1", "s2", "TEST DATA" );
producer.send(data, callback);
producer.close();
}
private static class TestCallback implements Callback {
@Override
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if (e != null) {
System.out.println("Error while producing message to topic :" + recordMetadata);
e.printStackTrace();
} else {
String message = String.format("sent message to topic:%s partition:%s offset:%s", recordMetadata.topic(), recordMetadata.partition(), recordMetadata.offset());
System.out.println(message);
}
}
}
已完成故障排除步骤:
有人可以在此线程上帮助我吗?
提前谢谢!
答案 0 :(得分:1)
您要描述的问题可以通过通过advertised.listeners
在互联网上为每个经纪人“广告”一个地址来解决。
telnet和nc检查端口是否打开(listeners
配置),但不能检查代理是否正确引导回客户端,您可以使用kafkacat -L -b <bootstrap>
来返回列表。集群中的代理,并且应该可以从要运行客户端的位置连接到每个代理
如果您在单个WAN地址后面有多个代理,则它们必须公告/转发单独的端口以实现完全连接
替代解决方案包括Kafka REST代理
无论哪种情况,都应将SSL添加到连接中