卡夫卡制片人无法通过Internet连接到经纪人。如果在本地网络中充当代理,效果很好。通过Internet进行Telnet连接

时间:2020-10-25 09:47:44

标签: apache-kafka kafka-consumer-api firewall kafka-producer-api windows-firewall

我的家庭网络上的计算机上运行着一个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);
           }
       }
   }

已完成故障排除步骤:

  1. 在3台不同的计算机,2台Windows和1台Mac上部署了Kafka。结果相同。从同一个网络运行良好,而不是在Internet上运行。 Telnet可从Internet /外部网络与每台kafka计算机配合使用。
  2. 尝试了3种不同的外部网络,其中之一是我的手机热点。
  3. 如上所述,在kafka机器上也尝试了其他软件,它们运行良好。
  4. 完全禁用系统防火墙,只是为了确保没有防火墙问题,但是没有运气。

有人可以在此线程上帮助我吗?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

您要描述的问题可以通过通过advertised.listeners在互联网上为每个经纪人“广告”一个地址来解决。

telnet和nc检查端口是否打开(listeners配置),但不能检查代理是否正确引导回客户端,您可以使用kafkacat -L -b <bootstrap>来返回列表。集群中的代理,并且应该可以从要运行客户端的位置连接到每个代理

如果您在单个WAN地址后面有多个代理,则它们必须公告/转发单独的端口以实现完全连接


替代解决方案包括Kafka REST代理

无论哪种情况,都应将SSL添加到连接中