一、写一个word-count案例,关于一些介绍已经在代码注释里面做了介绍,在这里就不用额外的篇幅来写一下storm的一下使用了
代码如下:
1.先写一个生成句子的spout,如下
/**
* @Auther: 18030501
* @Date: 2018/10/24 14:25
* @Description: 数据流生成者
*
* spout与bolt流程如下
* SentenceSpout-->SplitSentenceBolt-->WordCountBolt-->ReportBolt
*/
@Slf4j
public class SentenceSpout extends BaseRichSpout {
private SpoutOutputCollector collector;
private String[] sentences = {
"my name is whale",
"i like play games",
"my game name is The boy with the cannon",
"so no one dares to provoke me.",
"my girl friend is beautiful"
};
private int index = 0;
/**
* open()方法中是ISpout接口中定义,在Spout组件初始化时被调用。
* open()接受三个参数:
* 一个包含Storm配置的Map
* 一个TopologyContext对象,提供了topology中组件的信息
* SpoutOutputCollector对象提供发射tuple的方法
* 在这个例子中,我们不需要执行初始化,只是简单的存储在一个SpoutOutputCollector实例变量。
*/
@Override
public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
log.info("----SentenceSpout.open----");
this.collector = spoutOutputCollector;
}
/**
* nextTuple()方法是任何Spout实现的核心。
* Storm调用这个方法,向输出的collector发出tuple。
* 在这里,我们只是发出当前索引的句子,并增加该索引准备发射下一个句子。
*/
@Override
public void nextTuple() {
if (index < sentences.length){
this.collector.emit(new Values(sentences[index]));
index++;
}
Utils.sleep(1);
}
/**
* declareOutputFields是在IComponent接口中定义的,所有Storm的组件(spout和bolt)都必须实现这个接口
* 用于告诉Storm流组件将会发出那些数据流,每个流的tuple将包含的字段
*/
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
log.info("-----SentenceSpout.declareOutputFields----");
declarer.declare(new Fields("sentence"));
}
}
2、切分句子的Bolt
/**
* @Auther: 18030501
* @Date: 2018/10/24 14:41
* @Description: 单词分割器,订阅sentence spout发射的tuple流,实现分割单词
*/
@Slf4j
public class SplitSentenceBolt extends BaseRichBolt {
private OutputCollector collector;
/**
* prepare()方法类似于ISpout 的open()方法。
* 这个方法在blot初始化时调用,可以用来准备bolt用到的资源,比如数据库连接。
* 本例子和SentenceSpout类一样,SplitSentenceBolt类不需要太多额外的初始化,
* 所以prepare()方法只保存OutputCollector对象的引用。
*/
@Override
public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) {
log.info("----SplitSentenceBolt.prepare----");
this.collector = outputCollector;
}
/**
* SplitSentenceBolt核心功能是在类IBolt定义execute()方法,这个方法是IBolt接口中定义。
* 每次Bolt从流接收一个订阅的tuple,都会调用这个方法。
* 本例中,收到的元组中查找“sentence”的值,
* 并将该值拆分成单个的词,然后按单词发出新的tuple