簡體   English   中英

Storm:用於從端口讀取數據的Spout

[英]Storm : Spout for reading data from a port

我需要寫一個風暴噴口來從端口讀取數據。 想知道這在邏輯上是否可行。

考慮到這一點,我設計了一個簡單的拓撲結構,設計用於一個噴嘴和一個螺栓。 spout會收集使用wget發送的HTTP請求,而bolt會顯示請求 - 就是這樣。

我的噴口結構如下:

public class ProxySpout extends BaseRichSpout{
         //The O/P collector
         SpoutOutputCollector sc;
         //The socket
         Socket clientSocket;
         //The server socket
         ServerSocket sc;

         public ProxySpout(int port){
            this.sc=new ServerSocket(port);
            try{
                clientSocket=sc.accept();
            }catch(IOException ex){
                //Handle it
            }
         }

         public void nextTuple(){
            try{
                InputStream ic=clientSocket.getInputStream();
                byte b=new byte[8196];
                int len=ic.read(b);

                sc.emit(new Values(b));
                ic.close();
            }catch(//){
                //Handle it
            }finally{
                clientSocket.close();
            }
         }
}

我也實現了其余的方法。

當我將其轉換為拓撲並運行它時,我發送第一個請求時出錯:

了java.lang.RuntimeException:java.io.NotSerializableException:java.net.Socket中

只需要知道我實施這個噴口的方式是否有問題。 鯨魚噴水器甚至可以從端口收集數據嗎? 或者鯨魚噴水充當代理的實例?

編輯

搞定了。

代碼是:

   public class ProxySpout extends BaseRichSpout{
         //The O/P collector
         static SpoutOutputCollector _collector;
         //The socket
         static Socket _clientSocket;
         static ServerSocket _serverSocket;
         static int _port;

         public ProxySpout(int port){
          _port=port;
         }

         public void open(Map conf,TopologyContext context, SpoutOutputCollector collector){
           _collector=collector;
           _serverSocket=new ServerSocket(_port);
         }   

         public void nextTuple(){
            _clientSocket=_serverSocket.accept();
            InputStream incomingIS=_clientSocket.getInputStream();
            byte[] b=new byte[8196];
            int len=b.incomingIS.read(b);
            _collector.emit(new Values(b));
     }
}

根據@ Shaw的建議,嘗試在open()方法中初始化_serverSocket_clientSocketnextTuple()方法中運行以偵聽請求。

不知道這個的表現形式,但它有效.. :-)

在構造函數中只需分配變量。 嘗試在prepare方法中實例化ServerSocket,不要在構造函數中編寫任何新的... 並重命名變量,你有兩個sc變量。

public class ProxySpout extends BaseRichSpout{

    int port;

    public ProxySpout(int port){
        this.port=port;
    }

    @Override
    public void open(Map conf, TopologyContext context, SpoutOutputCollector collector)  { 
        //new ServerSocket
    }

    @Override
    public void nextTuple() {

    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {

    }
}

如果你把它放在prepare方法中,那么只有在已經部署了spout之后才會調用它,所以它不需要被序列化,並且它只會在每個spout生命周期被調用一次,所以它效率不高。

暫無
暫無

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

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