远程Kafka连接问题-代理可能不可用

时间:2019-10-15 19:53:54

标签: java maven apache-kafka

我正在学习Kafka,并已实现使用Maven的飞跃。

我在AWS中有一个独立的Kafka实例,在笔记本电脑上有一个Maven应用程序。我写了一个小应用程序,充当生产者

import org.apache.kafka.clients.KafkaClient;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;

import java.util.Properties;

public class ProducerDemo {

    public static void main(String[] args) {
        // create producer properties
        Properties properties = new Properties();

        properties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "<IP_TO_REMOTE_SERVER>:9092");

        properties.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        properties.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());

        //create producer
        KafkaProducer<String,String> producer = new KafkaProducer<String, String>(properties);

       //producer record
        ProducerRecord <String,String> record = new ProducerRecord<String, String>("first_topic", "jello there");
        System.out.println("SENDING RECORD");
        //send data - async
        producer.send(record);

        producer.flush();

        producer.close();
        System.out.println("complete");
    }
}

运行此命令时,似乎无法连接到远程实例。我收到以下错误。

  

[kafka-生产者网络线程|>生产者1]警告   org.apache.kafka.clients.NetworkClient-[生产者   clientId = producer-1]无法连接到节点0(/xx.xx.xx.xx:9092)   被建立。经纪人可能不可用。

     

[main] INFO org.apache.kafka.clients.producer.KafkaProducer-   [Producer clientId = producer-1]使用以下命令关闭Kafka生产者   timeoutMillis = 9223372036854775807 ms。

查看Stackoverflow之后,我将server.properties侦听器部分更新为服务器的专用IP

# The address the socket server listens on. It will get the value returned from 
# java.net.InetAddress.getCanonicalHostName() if not configured.
#   FORMAT:
#     listeners = listener_name://host_name:port
#   EXAMPLE:
#     listeners = PLAINTEXT://your.host.name:9092
listeners=PLAINTEXT://10.0.1.51:9092

我应该如何配置服务器上的Kafka使其可访问并进行远程侦听?

2 个答案:

答案 0 :(得分:1)

我想您面临的主要问题是从配置的角度来看。通过生产者进行交流之前,请检查是否已进行所有必要的更改。您需要进行以下更改:

卡夫卡变更: 您需要在Zookeeper.properties中为相关代理添加配置。

AWS更改:在连接到AWS时,您需要设置传递.pem文件的方式。您可能需要在AWS实例中启用直接访问。默认情况下,它将阻止所有未知流量。

其他方法: 我建议创建一个证书和密钥文件,该文件会将您自己的PC白名单作为有效来源。 将该证书添加到AWS服务器实例上的密钥库和信任库。 更改server.properties listeners = SSL://your.host.name:9092和您的BOOTSTRAP_SERVERS_CONFIG

答案 1 :(得分:0)

看到响应后,我开始考虑更改配置以使其正常工作。我找到了一篇非常好的博客文章,介绍了here这个问题。

我的设置

我会强调这不是生产。

公共子网中VPC中的单个AWS EC2实例。安装了Kafka。我正在使用Maven从笔记本电脑远程连接到Kafka作为制作人。

未更改 zookeeper.properties

更新了 server.properties ,特别是监听器 advertised.listeners

############################# Socket Server Settings #############################

# The address the socket server listens on. It will get the value returned from 
# java.net.InetAddress.getCanonicalHostName() if not configured.
#   FORMAT:
#     listeners = listener_name://host_name:port
#   EXAMPLE:
#     listeners = PLAINTEXT://your.host.name:9092
listeners=PLAINTEXT://<PRIVATE_IP_ADDRESS>:9092

# Hostname and port the broker will advertise to producers and consumers. If not set, 
# it uses the value for "listeners" if configured.  Otherwise, it will use the value
# returned from java.net.InetAddress.getCanonicalHostName().
advertised.listeners=PLAINTEXT://<PUBLIC_IP_ADDRESS>:9092

然后在我的Maven代码中,对于 BOOTSTRAP_SERVERS_CONFIG ,我引用公共IP

import org.apache.kafka.clients.KafkaClient;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;

import java.util.Properties;

public class ProducerDemo {

    public static void main(String[] args) {
        // create producer properties
        Properties properties = new Properties();

        properties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "<PUBLIC_IP_ADRESS>:9092");

        properties.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        properties.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());

        //create producer
        KafkaProducer<String,String> producer = new KafkaProducer<String, String>(properties);

       //producer record
        ProducerRecord <String,String> record = new ProducerRecord<String, String>("first_topic", "good pony");
        System.out.println("SENDING RECORD");
        //send data - async
        producer.send(record);

        producer.flush();

        producer.close();
        System.out.println("complete");
    }
}

这成功运行

  

发送记录

     

[kafka-producer-network-thread | producer-1] INFO   org.apache.kafka.clients.Metadata-[Producer clientId = producer-1]

     

[main] INFOorg.apache.kafka.clients.producer.KafkaProducer-[Producer   clientId = producer-1]使用timeoutMillis =关闭Kafka生产者   9223372036854775807毫秒

     

完成

我们看到文字被推送给消费者

enter image description here