简体   繁体   English

使用Camel-Kafka的ProducerTemplate sendBody()方法时,无法为端点创建Producer

[英]Failed to create Producer for endpoint when using Camel-Kafka's ProducerTemplate sendBody() method

I am testing simple producer to send messages on Kafka (0.8.2.1) using Apache Camel. 我正在测试简单的生产者,以使用Apache Camel在Kafka(0.8.2.1)上发送消息。 I have created endpoint using java DSL in camel. 我在骆驼中使用Java DSL创建了端点。

CamelContext ctx =new DefaultCamelContext();
PropertiesComponent properties=new PropertiesComponent();

properties.setLocation("com/camel/test/props.properties");
ctx.addComponent("properties",properties);

final String uri= "kafka://{{kafka.host}}?topic={{topic}}&zookeeperHost={{zookeeperHost}}&zookeeperPort={{zookeeperPort}}";
String uriParams = "&metadata.broker.list={{metadata.broker.list}";

ctx.addRoutes(new RouteBuilder() {
    public void configure() { //
        from(uri+"&groupId={{groupId}}")
        .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                System.out.println(exchange.getIn().getBody());
            }
        })
        ;
    }
});


ctx.start();

ProducerTemplate tmp = ctx.createProducerTemplate();
tmp.sendBody(ctx.getEndpoint(uri), "my test is working");// Error occurs here

now I want to send message on kafka using ProducerTempalte provided by Apache Camel. 现在我想使用Apache Camel提供的ProducerTempalte在kafka上发送消息。 but I get below error when runs the program Note: Zookeeper & Kafka are up and can produce/consume messages using kafka console. 但运行程序时出现以下错误注意:Zookeeper和Kafka已启动,可以使用kafka控制台生成/使用消息。

Exception in thread "main" org.apache.camel.FailedToCreateProducerException: Failed to create Producer for endpoint: Endpoint[kafka://localhost:9092?topic=test&zookeeperHost=localhost&zookeeperPort=2181]. Reason: java.lang.NullPointerException
    at org.apache.camel.impl.ProducerCache.doGetProducer(ProducerCache.java:407)
    at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:220)
    at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:343)
    at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:184)
    at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:124)
    at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:137)
    at com.camel.test.CamelTest.main(CamelTest.java:45)
Caused by: java.lang.NullPointerException
    at java.util.Hashtable.put(Hashtable.java:514)
    at org.apache.camel.component.kafka.KafkaProducer.getProps(KafkaProducer.java:54)
    at org.apache.camel.component.kafka.KafkaProducer.doStart(KafkaProducer.java:61)
    at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
    at org.apache.camel.impl.DefaultCamelContext.startService(DefaultCamelContext.java:2869)
    at org.apache.camel.impl.DefaultCamelContext.doAddService(DefaultCamelContext.java:1097)
    at org.apache.camel.impl.DefaultCamelContext.addService(DefaultCamelContext.java:1058)
    at org.apache.camel.impl.ProducerCache.doGetProducer(ProducerCache.java:405)
    ... 6 more

I guess the properties are not set for the producer but have no idea how to set in producer template. 我猜没有为生产者设置属性,但是不知道如何在生产者模板中设置属性。

uri应该将代理列表作为服务器名称(不要怪我没有创建此组件的语法)。

final String uri= "kafka://{{metadata.broker.list}}?topic={{topic}}&zookeeperHost={{zookeeperHost}}&zookeeperPort={{zookeeperPort}}";

I was able to find the solution by debugging. 我能够通过调试找到解决方案。 By default ProducerTemplate need default parameters which are not set when new object is created (this might be a bug in API). 默认情况下,ProducerTemplate需要使用默认参数,这些参数在创建新对象时未设置(这可能是API中的错误)。 So I found a way to send params through URI. 因此,我找到了一种通过URI发送参数的方法。 where below params are mandatory 其中以下参数是强制性的

  • metadata.broker.list (as URI param) metadata.broker.list(作为URI参数)
  • request.required.acks (Already set By default) request.required.acks(默认情况下已设置)
  • producer.type (Not required in this case but needed for other APIs) producer.type(在这种情况下不是必需的,但其他API则需要)
  • serializer.class (Already set by default) serializer.class(默认情况下已设置)
  • partitioner (class) (as URI param) 分区程序(类)(作为URI参数)
  • PARTITION_KEY (as Header) PARTITION_KEY(作为标题)

We do not have an option to send param for Partition_key so need to add it in Header. 我们没有为Partition_key发送参数的选项,因此需要在Header中添加它。 So use sendBodyAndHeader method to send producer message. 因此,使用sendBodyAndHeader方法发送生产者消息。

        ProducerTemplate tmp = ctx.createProducerTemplate();

        tmp.setDefaultEndpoint(ctx.getEndpoint(uri+"&partitioner={{partitioner.class}}"));
        ctx.start();
        tmp.sendBodyAndHeader("my test is working "+(new Random()).nextInt(100), KafkaConstants.PARTITION_KEY, 1);
        tmp.stop();
        ctx.stop();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM