部署项目实例storm_helloworld
1、在eclipse中新建一个maven project(步骤见:https://blog.csdn.net/zytmaster/article/details/101316066)
2、打开pom.xml文件,添加依赖(在</project>前面添加)
添加内容如下:
<dependencies> <dependency> <groupId>org.apache.storm</groupId> <artifactId>storm-core</artifactId> <version>0.9.2-incubating</version> </dependency> </dependencies>
保存,等待添加依赖……
注意:添加依赖的内容在官网maven.apache.org搜索storm-core,寻找与电脑安装的版本一致的那项,点击就可查看依赖关系的配置内容,复制到pom.xml文档中,保存,等待,即可。
3、根据storm组件图所示的流程,编写java代码
代码思路如下:
- 首先编写数据源类:Spout。可以使用两种方式: ①继承BaseRichSpout类 ②实现IRichSpout接口
重点需要几个方法进行重写或实现:open、nextTuple、declareOutputFields
- 编写数据处理类:Bolt。可以使用两种方式: ①继承BaseBasicBolt类 ②实现IRichBolt接口
重点需要几个方法进行重写或实现:execute、declareOutputFields
- 编写主函数(Topolopy)进行提交一个任务。
在使用Topology的时候,Storm框架提供了两种模式:本地模式和集群模式
本地模式:无需Storm集群,直接在java中即可运行,一般用于测试和开发阶段。直接运行main函数即可。
集群模式:需要Storm集群,把实现的java程序打包,然后提交Topology到集群上。
代码如下:
①PWSpout类
package com.zyt.storm.spout; import java.util.HashMap; import java.util.Map; import java.util.Random; 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 PWSpout extends BaseRichSpout{ private SpoutOutputCollector collector; private static Map<Integer, String> map = new HashMap<Integer,String>(); static{ map.put(0, "java"); map.put(1, "storm"); map.put(2, "scala"); map.put(3, "hadoop"); map.put(4, "bigdata"); } /** * 初始化 */ @Override public void open(Map map, TopologyContext context, SpoutOutputCollector collector) { //对spout初始化 this.collector = collector; } /** * 轮询 */ @Override public void nextTuple() { Random r = new Random(); int num = r.nextInt(5); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //发送数据 collector.emit(new Values(map.get(num))); } /** * 定义发送数据的字段名 */ @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields("print")); } }
②PrintBolt类
package com.zyt.storm.bolt; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import backtype.storm.topology.BasicOutputCollector; import backtype.storm.topology.OutputFieldsDeclarer; import backtype.storm.topology.base.BaseBasicBolt; import backtype.storm.tuple.Fields; import backtype.storm.tuple.Tuple; import backtype.storm.tuple.Values; public class PrintBolt extends BaseBasicBolt{ /** * */ private static final long serialVersionUID = 1144598570286612594L; private static Log log = LogFactory.getLog(PrintBolt.class); /** * 处理数据 */ @Override public void execute(Tuple input, BasicOutputCollector collector) { //接收数据 String print = input.getStringByField("print"); //数据写到日志中 log.info("【print】:"+print); collector.emit(new Values(print)); } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields("write")); } }
③WriteBolt类
package com.zyt.storm.bolt; import java.io.FileWriter; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import backtype.storm.topology.BasicOutputCollector; import backtype.storm.topology.OutputFieldsDeclarer; import backtype.storm.topology.base.BaseBasicBolt; import backtype.storm.tuple.Tuple; public class WriteBolt extends BaseBasicBolt { private static final long serialVersionUID = 4976229129083909695L; private static Log log = LogFactory.getLog(WriteBolt.class); private FileWriter fw; @Override public void execute(Tuple input, BasicOutputCollector collecteor) { //接收数据 String write = input.getStringByField("write"); try { if(fw == null){ if(System.getProperty("os.name").equalsIgnoreCase("Windows 10")){ fw = new FileWriter("D:\\stormtest\\"+this); }else if(System.getProperty("os.name").equalsIgnoreCase("Windows 8.1")){ fw = new FileWriter("D:\\stormtest\\"+this); }else if(System.getProperty("os.name").equalsIgnoreCase("Windows 7")){ fw = new FileWriter("D:\\stormtest\\"+this); }else if(System.getProperty("os.name").equalsIgnoreCase("Linux")){ fw = new FileWriter("/home/temp/"+this); } } log.info("【write】:写入文件"); //把数据写到文件中 fw.write(write); fw.write("\n"); fw.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void declareOutputFields(OutputFieldsDeclarer arg0) { // TODO Auto-generated method stub } }
④PWTopology类
package com.zyt.storm.topolopy; import com.zyt.storm.bolt.PrintBolt; import com.zyt.storm.bolt.WriteBolt; import com.zyt.storm.spout.PWSpout; import backtype.storm.Config; import backtype.storm.LocalCluster; import backtype.storm.StormSubmitter; import backtype.storm.generated.AlreadyAliveException; import backtype.storm.generated.InvalidTopologyException; import backtype.storm.topology.TopologyBuilder; public class PWTopolopy { public static void main(String[] args) { // TODO Auto-generated method stub //创建一个拓扑的配置对象 Config cfg = new Config(); //启动两个worker进程 cfg.setNumWorkers(2); cfg.setDebug(true); //创建Topology类 TopologyBuilder builder = new TopologyBuilder(); //组织spout和bolt builder.setSpout("spout", new PWSpout()); builder.setBolt("print bolt", new PrintBolt()).shuffleGrouping("spout"); builder.setBolt("write bolt", new WriteBolt()).shuffleGrouping("print bolt"); //本地模式 ,用于本地测试代码,成功后上传到集群上 LocalCluster cluster = new LocalCluster(); //提交Topology cluster.submitTopology("top1", cfg, builder.createTopology()); //休息十秒后,关闭拓扑 try { Thread.sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } cluster.killTopology("top1"); //关闭本地集群 cluster.shutdown(); // //集群模式 // try { // StormSubmitter.submitTopology("top1", cfg, builder.createTopology()); // } catch (AlreadyAliveException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (InvalidTopologyException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // //两者不要同时运行 // } } }
先在用本地模式查看程序结果是否有错,没错后将项目提交到集群上
将项目打成jar包
方法①到该项目的目录下打开cmd,运行命令:mvn package
方法②在eclipse中右击该文件,选择run as-->maven build...-->输入命令package
前提:
①已创建三台虚拟机(storm01,storm02,storm03),并搭建好集群(搭建storm集群见:https://blog.csdn.net/zytmaster/article/details/100371757)
②启动zookeeper集群,查看状态
zkServer.sh start
zkServer.sh status
③启动UI界面(方便查看任务提交运行情况)
storm ui&
④启动主节点(在主节点上运行)
storm nimbus&
⑤启动两个从节点(在两个从节点上运行)
storm supervisor&
⑥查看进程(看进程是否都正常启动)
jps
将jar包上传到storm01的stormjars文件夹(创建)下(执行rz命令)
提交拓扑:
命令: storm jar storm_helloworld-0.0.1-SNAPSHOT.jar com.zyt.storm.topolopy.PWTopology
注:storm jar 上传的jar包名称 代码中PWTopology类的全名称
查看集群上运行的任务(查看任务是否正常运行)
方法一:执行命令 storm list
方法二:从UI界面上查看(打开浏览器输入网址:storm01的IP地址:8080)
查看两台从节点的进程(jps),会出现worker进程
查看两台从节点日志信息,会出现worker日志
从节点日志信息:%STORM_HOME%\logs
动态查看文档,执行命令:tail -f 文档名
对任务进行操作的命令
暂停任务命令:storm deactivate top1
激活任务命令:storm activate top1
停止任务命令:storm kill top1
注:top1是提交的拓扑任务的名称