storm spout读取mysql,Storm:用于从端口读取数据的Spout

I need to write a storm spout for reading data from a port. Wanted to know if that was logically possible.

With that in mind, I had designed a simple topology designed for the same with one spout and one bolt. The spout would gather HTTP requests sent using wget and the bolt would display the request-Just that.

My spout structure is as follows:

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();

}

}

}

I have implemented the rest of the methods too.

When I turn this into a topology and run it, I get an error when I send the first request:

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

Just need to know if there is something wrong with the way I am implementing this spout. Is it even possible for a spout to collect data from a port? Or for a spout to act as an instance of a proxy?

Edit

Got it working.

The code is:

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));

}

}

As per @Shaw's suggestion, tried initializing _serverSocket in the open() method and the _clientSocket runs in nextTuple() method for listening to requests.

Dunno the performance metrices of this one, but it works..:-)

解决方案

In constructor just assign the variables. Try to instantiate ServerSocket in prepare method, do not write any new ... in constructor. And rename variables, you have two sc variables.

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) {

}

}

If you put it in prepare method then it will only be called once the spout is already deployed, so it doesn't need to be serialized, and it will only be called once per lifetime of the spout, so it's not inefficient.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值