3.1 Storm 代码总体流程
3.1.1 Spout 类编写
首先编写我们的数据源类:Spout。可以使用两种方式。
1. 继承 BaseRichSpout 类
2. 实现 IRichSpout 接口
重点需要几个方法进行实现和重写,open、nextTuple、declareOutputFields
3.1.2 Bolt 类编写
继续编写我们的数据处理类:Blot。可以使用两种方式。
1. 继承 BaseBasicBlot 类
2. 实现 IRichBlot 接口
重点需要几个方法进行实现和重写,execute、declareOutputFields
3.1.3 Topology 类编写
最后我们需要编写一个 Topology 类提交一个任务。
在使用 Topology 的时候, Storm 框架为我们提供两种模式,本地模式和集群模式。
1. 本地模式:执行运行 main 即可(无需 Storm 集群,直接在 java 中既可运行,一般用于测试和开发阶段)
2. 集群模式:需要把应用打成 jar,使用 storm 命令把 Topology 提交到集群上去。(需要要 Storm 集群,把实现的 java 程序打包,然后 Topology 进行提交)。
3.2 代码实现
public class PWSpout extends BaseRichSpout {
private static final long serialVersionUID = 7686619786974521530L;
private SpoutOutputCollector collector;
private static Map<Integer, String> map = new HashMap<Integer, String>();
static {
map.put(0, "c++");
map.put(1, "php");
map.put(2, "java");
map.put(3, "ruby");
map.put(4, "python");
}
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
// 对 SpoutOutputCollector 初始化
this.collector = collector;
}
public void nextTuple() {
final Random r = new Random();
int num = r.nextInt(5);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.collector.emit(new Values(map.get(num)));
}
/**
* 这个方法用于进入下一个环节
* new Fields("print") 指定进入 print 这个节点做处理
*/
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("print"));
}
}
public class PrintBolt extends BaseBasicBolt {
private static final long serialVersionUID = -7838926192790471487L;
private static final Logger log = LoggerFactory.getLogger(PrintBolt.class);
public void execute(Tuple input, BasicOutputCollector collector) {
//获取上一个组件所声明的Field
String print = input.getStringByField("print");
log.info("【print】: " + print);
collector.emit(new Values(print));
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("write"));
}
}
public class WriteBolt extends BaseBasicBolt {
private static final long serialVersionUID = 877938715356485328L;
private static final Logger log = LoggerFactory.getLogger(PrintBolt.class);
public void execute(Tuple input, BasicOutputCollector collector) {
String write = input.getStringByField("write");
String id = UUID.randomUUID().toString().replaceAll("-", "");
log.info("【write】: " + write + " - 【id】: " + id);
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
}
}
public class PWTopology1 {
public static void main(String[] args) throws Exception {
Config cfg = new Config();
cfg.setNumWorkers(2);
cfg.setDebug(true);
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("spout", new PWSpout());
builder.setBolt("print-bolt", new PrintBolt()).shuffleGrouping("spout");
builder.setBolt("write-bolt", new WriteBolt()).shuffleGrouping("print-bolt");
//1 本地模式
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("top1", cfg, builder.createTopology());
Thread.sleep(1000000);
cluster.killTopology("top1");
cluster.shutdown();
// linux 环境上使用,上面的本地模式删掉
// StormSubmitter.submitTopology("top1", cfg, builder.createTopology());
}
}
window 上运行
部署到 Linux 环境上
storm jar storm1-1.0.0-SNAPSHOT.jar com.ws.topology.PWTopology1
storm list 查看运行的情况
在 storm 的管控台上可以看到 top1 的 Topology