簡體   English   中英

在Apache Storm bolt中使用Apache Camel ProducerTemplate

[英]Using Apache Camel ProducerTemplate in Apache Storm bolt

我正在嘗試編寫簡單的Storm + Camel項目。 我的Storm拓撲分析推文和一個bolt應該發送推文文本到apache camel路由,而后者又使用websocket通知一些webapp。

由於在嘗試使用CamelContext構建時從螺栓接收的NotSerializableExceptions,我無法使其工作。

我已經嘗試過的:

  • 在bolt的構造函數中傳遞CamelContext - 導致NotSerializableException
  • 在storm conf中傳遞CamelContext,並在bolt的prepare(...)方法中使用它來gian訪問它。 結果是 :

    14484 [main]錯誤org.apache.storm.zookeeper.server.NIOServerCnxnFactory - Thread Thread [main,5,main] death java.lang.IllegalArgumentException:拓撲conf在backtype.storm.testing上不是json-serializable $ submit_local_topology.invoke (testing.clj:262)〜[storm-core-0.9.4.jar:0.9.4] at backtype.storm.LocalCluster $ _submitTopology.invoke(LocalCluster.clj:43)〜[storm-core-0.9.4。 jar:0.9.4] at backtype.storm.LocalCluster.submitTopology(Unknown Source)〜[storm-core-0.9.4.jar:0.9.4]

駱駝路線:

public class MyRouteBuilder extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("direct:main")
                .to("websocket:localhost:8085/main?sendToAll=true");
    }
}

Storm Topology:Tweet Spout正在使用twitter4j stremaing API傳播推文。

public class TwitterStreamTopology {

    public static void main(String[] args) {
        CamelContext producerTemplate = new RouteStarter().buildRoute();

        TopologyBuilder builder = new TopologyBuilder();
        builder.setSpout("tweetSpout", new TweetSpout(keywords), 1);
        builder.setBolt("websocket", new WebSocketBolt()).shuffleGrouping("tweetSpout");
        Config conf = new Config();
        conf.put("producerTemplate", producerTemplate.createProducerTemplate());
        conf.setDebug(true);

        LocalCluster cluster = new LocalCluster();
        cluster.submitTopology("mytopology", conf, builder.createTopology());

        Utils.sleep(20000);
        cluster.shutdown();
    }
}

WebsocketBolt:

public class WebSocketBolt extends BaseBasicBolt {
    private ProducerTemplate producerTemplate;

    @Override
    public void execute(Tuple input, BasicOutputCollector basicOutputCollector) {
        Status s = (Status) input.getValueByField("tweet");
        producerTemplate.sendBody("direct:main", s.getText());
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {

    }

    @Override
    public void prepare(Map stormConf, TopologyContext context) {
        super.prepare(stormConf, context);
        this.producerTemplate = (ProducerTemplate) stormConf.get("producerTemplate");
    }
}

有沒有辦法很好地做到這一點?

或者我應該通過http訪問駱駝路由,並在bolt prepare(...)方法中創建一些HttpClient? 這仍然看起來有點矯枉過正,必須有一種方法讓它變得更容易。

謝謝大家的幫助!

您的問題的根本原因是您正在向您的風暴配置添加ProducerTemplate,並且它正在拋出異常,因為它不可序列化。 如果那是你自己的類,你可以改變代碼使其工作,但由於這是一個Camel類,我會推薦一種不同的方法。

  1. WebSocketBolt:將您的producerTemplate私有成員更改為transient: private transient ProducerTemplate producerTemplate; 這樣就不會嘗試序列化了(將它置於conf中也有同樣的問題)。
  2. WebSocketBolt:在prepare方法中而不是在拓撲中初始化producerTemplate。

像這樣的東西:

public class WebSocketBolt extends BaseBasicBolt {
    private transient ProducerTemplate producerTemplate;

    @Override
    public void execute(Tuple input, BasicOutputCollector basicOutputCollector) {
        Status s = (Status) input.getValueByField("tweet");
        producerTemplate.sendBody("direct:main", s.getText());
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {

    }

    @Override
    public void prepare(Map stormConf, TopologyContext context) {
        super.prepare(stormConf, context);
        CamelContext producerTemplate = new RouteStarter().buildRoute();
        this.producerTemplate = producerTemplate.createProducerTemplate();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM