KafkaProducer始终在Java API中选择localhost:8081作为模式注册表

时间:2018-10-31 13:39:02

标签: java apache-kafka kafka-producer-api confluent-schema-registry

KafkaProducer无法选择其属性中定义的schema.registry.url

如下面的屏幕截图所示,架构注册表网址是虚拟网址

// variable which is being debugged
private KafkaProducer<K, V> kafkaFullAckProducer;

enter image description here

但是仍然在我的日志中,使用KafkaProducer发布消息失败,主机为http://0:8081

{"@timestamp":"2018-10-31T18:57:37.906+05:30","message":"Failed to send HTTP request to endpoint: http://0:8081/subjects/

以上两个证明是在程序的一次运行中获得的。正如我们可以清楚地看到的那样,在日食调试过程中提示的schmearegistry url提示为123.1.1.1,但是如果我的日志失败,则提示为http://0

因为这在我的其他环境中,所以我无法运行其他分配的schema.registry.url,因为它始终使用http://0

该代码托管在一台计算机上,而模式注册表/代理位于另一台计算机上。

注册表是在开发环境中启动的。/confluentstart

我的生产者代码:

private KafkaProducer<K, V> kafkaFullAckProducer;
MonitoringConfig config;

public void produceWithFullAck(String brokerTopic, V genericRecord) throws Exception {
    // key is null
    ProducerRecord<K, V> record = new ProducerRecord<K, V>(brokerTopic, genericRecord);
    try {
        Future<RecordMetadata> futureHandle = this.kafkaFullAckProducer.send(record, (metadata, exception) -> {

            if (metadata != null) {
                log.info("Monitoring - Sent record(key=" + record.key() + " value=" + record.value()
                        + " meta(partition=" + metadata.partition() + " offset=" + metadata.offset() + ")");
            }
        });
        RecordMetadata recordMetadata = futureHandle.get();

    } catch (Exception e) {
        if (e.getCause() != null)
            log.error("Monitoring - " + e.getCause().toString());
        throw new RuntimeException(e.getMessage(), e.getCause());
    } finally {
        // initializer.getKafkaProducer().close();
    }
}

@PostConstruct
private void initialize() {
    Properties props = new Properties();
    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, config.getBrokerList());
    props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, KafkaAvroSerializer.class.getName());
    // kafkaProps.put("value.serializer",
    // "org.apache.kafka.common.serialization.ByteArraySerializer");
    props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, CustomAvroSerializer.class.getName());
    props.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, Constants.COMPRESSION_TYPE_CONFIG);
    props.put(ProducerConfig.RETRIES_CONFIG, config.getProducerRetryCount());
    props.put("schema.registry.url", config.getSchemaRegistryUrl()); // the url is coming right here 
    props.put("acks", "all");
    kafkaFullAckProducer = new KafkaProducer<K, V>(props);
}

MonitoringConfig:     公共类MonitoringConfig {

    @Value("${kafka.zookeeper.connect}")
    private String zookeeperConnect;

    @Value("${kafka.broker.list}")
    private String brokerList;

    @Value("${consumer.timeout.ms:1000}")
    private String consumerTimeout;

    @Value("${producer.retry.count:1}")
    private String producerRetryCount;

    @Value("${schema.registry.url}")
    private String schemaRegistryUrl;

    @Value("${consumer.enable:false}")
    private boolean isConsumerEnabled;

    @Value("${consumer.count.thread}")
    private int totalConsumerThread;
}

application.properties:

kafka.zookeeper.connect=http://localhost:2181
kafka.broker.list=http://localhost:9092
consumer.timeout.ms=1000
producer.retry.count=1
schema.registry.url=http://123.1.1.1:8082

自定义avro序列化程序是我需要弃用并使用讨论的here的方式,但是我确定这不是此问题的原因。

以下是主机的详细信息: 主机1:有此Java服务和Kafka Connect,错误日志在此处。 主持人2:拥有Kafka,Schema Registry和Zookeper。

1 个答案:

答案 0 :(得分:2)

您正在使用自定义序列化程序,并且作为Serializer实现的一部分,您必须定义一个configure方法来接受Map。

在该方法中,我猜您定义了一个CachedSchemaRegistryClient字段,但是没有从配置映射中提取在Producer级别添加的url属性,因此它将默认使用其他本地主机地址

Confluent代码需要逐步完成四个类,但是您将看到Serializer实现here,然后看一下单独的Config类以及Abstract Serializer和SerDe父类。在your previous post中,我指出我并不需要实际使用自定义Avro序列化程序,因为您似乎正在重做AbstractKafkaSerializer类的作用