经过前面两次学习笔记的介绍相信大家已经对storm的基本运行原理有了初步认识,
下面我们通过一个简单的小例子理解下:
需求:做一个wordsum的程序
1+2+3+4+5.............
环境 : eclipse mar
apache-storm-0.9.4
链接: 所有需要的jar都已经为大家准备好了放在lib下,大家下回去,使用时千万别忘了buildpath下,源码包一起提供,大家没事也可以跟进去看看 https://pan.baidu.com/s/1wWQq6ZzO5acHIAi4ivw-DQ
按照步骤走 Spout->Bolt->test测试
创建WsSpout类,代码如下
这里不用考虑变量i累加的问题,因为进程会自动一直发送
package com.zxy.storm;
import java.util.List;
import java.util.Map;
import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values;
public class WsSpout extends BaseRichSpout
{
private static final long serialVersionUID = 1L;
Map map;
TopologyContext context;
SpoutOutputCollector collector;
int i=0;
@Override
public void nextTuple()
{
i++;
List list = new Values(i);
collector.emit(list);
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.err.println("spout emit +++++++"+ list);
}
@Override
public void open(Map map, TopologyContext context, SpoutOutputCollector collector)
{
this.map=map;
this.context=context;
this.collector=collector;
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer)
{
//n是随便定义的一个字段名字,便于后面的Bolt接收
declarer.declare(new Fields("n"));
}
}
值得注意的是
List list = new Values(i);
collector.emit(list);
collector.emit方法需要的是一个Tuple类型的参数,但是Tuple是一个接口不能实例化,这里实际封装数据的是
Values,而Values又继承了ArrayList,所以为了后期更灵活这里用了多态的写法
List list = new Values(i);
创建WsBolt类,代码如下
package com.zxy.storm;
import java.util.Map;
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Tuple;
public class WsBolt extends BaseRichBolt
{
Map stormConf;
private TopologyContext context;
private OutputCollector collector;
int sum=0;
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector)
{
this.stormConf=stormConf;
this.context=context;
this.collector=collector;
}
@Override
public void execute(Tuple input)
{
//接受数据
int number = input.getIntegerByField("n");
//处理数据
sum+=number;
//发送数据
System.err.println("sum======="+sum);
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer)
{
//没有下一个Bolt了
}
}
创建Test类,代码如下
package com.zxy.storm;
import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.topology.TopologyBuilder;
public class Test
{
public static void main(String[] args)
{
TopologyBuilder tb=new TopologyBuilder();
tb.setSpout("ws", new WsSpout());
tb.setBolt("wsbolt",new WsBolt() ).shuffleGrouping("ws");
//本地模式,测试
LocalCluster localCluster = new LocalCluster();
localCluster.submitTopology("wordsum",new Config(), tb.createTopology());
}
}
执行结果如下 因为sleep了一下所以emit和sum结果显示顺序不固定
6697 [Thread-11-wsb] INFO backtype.storm.daemon.executor - Prepared bolt wsb:(3)
sum=======1
6712 [Thread-13-__system] INFO backtype.storm.daemon.executor - Preparing bolt __system:(-1)
6716 [Thread-13-__system] INFO backtype.storm.daemon.executor - Prepared bolt __system:(-1)
6729 [Thread-15-__acker] INFO backtype.storm.daemon.executor - Preparing bolt __acker:(1)
6731 [Thread-15-__acker] INFO backtype.storm.daemon.executor - Prepared bolt __acker:(1)
spout emit +++++++[1]
sum=======3
spout emit +++++++[2]
sum=======6
spout emit +++++++[3]
sum=======10
spout emit +++++++[4]
sum=======15
spout emit +++++++[5]
sum=======21
spout emit +++++++[6]
sum=======28
spout emit +++++++[7]
sum=======36
spout emit +++++++[8]
代码写的比较烂大家见谅,后面再为大家介绍下 flume+kafka+storm的应用这个非常实用,一般做个ETL或long还是很不错的
但是之前storm可能还需要介绍下其他相关知识,大家慢慢体会下
sq11W1WWQ