一、配置开发环境

storm有两种操作模式: 本地模式和远程模式。使用本地模式的时候,你可以在你的本地机器上开发测试你的topology, 一切都在你的本地机器上模拟出来; 用远程模式的时候你提交的topology会在一个集群的机器上执行。

建议使用maven,只需要加上storm的依赖就可以了。

<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.1.0</version>
<scope>provided</scope>
</dependency>

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>cn.ljh.storm</groupId>
<artifactId>storm-helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>storm-helloworld</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>cn.ljh.storm.helloworld.ExclamationTopology</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

二、HelloWorld关联代码

ExclamationTopology.java

package cn.ljh.storm.helloworld;

import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.StormSubmitter;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.utils.Utils; public class ExclamationTopology {
public static void main(String[] args) throws Exception {
TopologyBuilder builder = new TopologyBuilder(); builder.setSpout("word", new TestWordSpout(), 1);
builder.setBolt("exclaim", new ExclamationBolt(), 1).shuffleGrouping("word");
builder.setBolt("print", new PrintBolt(), 1).shuffleGrouping("exclaim"); Config conf = new Config();
conf.setDebug(true); if (args != null && args.length > 0) {
conf.setNumWorkers(3); StormSubmitter.submitTopologyWithProgressBar(args[0], conf, builder.createTopology());
}
else { LocalCluster cluster = new LocalCluster();
cluster.submitTopology("test3", conf, builder.createTopology());
Utils.sleep(20000);
cluster.killTopology("test3");
cluster.shutdown();
}
}
}

TestWordSpout.java

package cn.ljh.storm.helloworld;

import org.apache.storm.topology.OutputFieldsDeclarer;
import java.util.Map;
import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.base.BaseRichSpout;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;
import org.apache.storm.utils.Utils;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class TestWordSpout extends BaseRichSpout {
public static Logger LOG = LoggerFactory.getLogger(TestWordSpout.class);
SpoutOutputCollector _collector; public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
_collector = collector;
} public void nextTuple() {
Utils.sleep(100);
final String[] words = new String[] {"nathan", "mike", "jackson", "golda", "bertels"};
final Random rand = new Random();
final String word = words[rand.nextInt(words.length)];
_collector.emit(new Values(word));
} public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
}
}

ExclamationBolt.java

package cn.ljh.storm.helloworld;

import java.util.Map;

import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values; public class ExclamationBolt extends BaseRichBolt {
OutputCollector _collector; public void prepare(Map conf, TopologyContext context, OutputCollector collector) {
_collector = collector;
} public void execute(Tuple tuple) {
_collector.emit(tuple, new Values(tuple.getString(0) + "!!!"));
_collector.ack(tuple);
} public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
} }

PrintBolt.java

package cn.ljh.storm.helloworld;

import java.util.Map;

import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.tuple.Tuple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class PrintBolt extends BaseRichBolt {
private static Logger LOG = LoggerFactory.getLogger(PrintBolt.class);
OutputCollector _collector; public void prepare(Map conf, TopologyContext context, OutputCollector collector) {
_collector = collector;
} public void execute(Tuple tuple) {
LOG.info(tuple.getString(0) + " Hello World!");
_collector.ack(tuple);
} public void declareOutputFields(OutputFieldsDeclarer declarer) {
}
}

三、实际运行

storm有本地模式和远程模式。

1、本地模式

本地模式一般用于测试和开发阶段,直接在Eclipse执行ExclamationTopology的main函数进行。

本地模式的代码中有设置睡眠时间,到时间后主动kill topoloyg。

Utils.sleep(20000);

开始设置的时间是10S,运行log中没有期待的输出,反而出现以下错误。

org.apache.storm.shade.org.apache.zookeeper.server.ServerCnxn$EndOfStreamException: Unable to read additional data from client sessionid 
    0x15c8a2872ac000f, likely client has closed socket
at org.apache.storm.shade.org.apache.zookeeper.server.NIOServerCnxn.doIO(NIOServerCnxn.java:228) [storm-core-1.1.0.jar:1.1.0]
at org.apache.storm.shade.org.apache.zookeeper.server.NIOServerCnxnFactory.run(NIOServerCnxnFactory.java:208) [storm-core-1.1.0.jar:1.1.0]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_121]

后面设置时间为20S,运行log中也有上面错误,但是有期待的输出。

原因是机器比较慢,还没初始化完就到时间跳出了,所以把睡眠时间设置大些。

2、远程模式

集群模式需要先创建一个包含程序代码以及代码所依赖的依赖包的jar包(有关storm的jar包不用包括, 这些jar包会在工作节点上自动被添加到classpath里面去)。如果使用maven, 那么插件:Maven Assembly Plugin可以帮你打包,只要把下面的配置加入pom.xml。

<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>cn.ljh.storm.helloworld.ExclamationTopology</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

然后运行mvn assembly:assembly就可以打包了.

(1)用storm提交topology

storm jar storm-helloworld-0.0.1-SNAPSHOT-jar-with-dependencies.jar cn.ljh.storm.helloworld.ExclamationTopology ExclamationTest

运行提交命令后,出现如下log,说明提交成功。

查看集群的进程jps,两个Supervisor节点出现了worker进程

在Nimbus节点的/usr/local/storm/data/nimbus/inbox下面有提交的jar

UI界面显示提交topology

(2)终止一个topology

要终止一个topology, 执行:

storm kill {stormname}

其中{stormname}是提交topology给storm集群的时候指定的名字。

storm不会马上终止topology。相反,它会先终止所有的spout,让它们不再发射任何新的tuple, storm会等Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS秒之后才杀掉所有的工作进程。这会给topology足够的时 间来完成所有我们执行storm kill命令的时候还没完成的tuple。

(3)更新一个运行中的topology

为了更新一个正在运行的topology, 唯一的选择是杀掉正在运行的topology然后重新提交一个新的。

至此HelloWorld示例完成。

四、常见配置

有很多topology级的配置可以设。 以”TOPOLOGY”打头的配置是topology级别的配置,可以覆盖全局级别的配置。下面是一些比较常见的:

1)Config.TOPOLOGY_WORKER设置:  这个设置用多少个工作进程来执行这个topology。比如,如果你把它设置成25, 那么集群里面一共会有25个java进程来执行这个topology的所有task。如果你的这个topology里面所有组件加起来一共有150的并行 度,那么每个进程里面会有6个线程(150 / 25 = 6)。

2)Config.TOPOLOGY_ACKERS: 这个配置设置acker线程的数目。Ackers是Storm的可靠性API的一部分。

3)Config.TOPOLOGY_MAX_SPOUT_PENDING:  这个设置一个spout task上面最多有多少个没有处理的tuple(没有ack/failed)回复, 我们推荐你设置这个配置,以防止tuple队列爆掉。

4)Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS: 这个配置storm的tuple的超时时间  – 超过这个时间的tuple被认为处理失败了。这个设置的默认设置是30秒,对于大多数的topology都已经足够了。

5)Config.TOPOLOGY_SERIALIZATIONS: 为了在你的tuple里面使用自定义类型,你可以用这个配置注册自定义serializer。

torm入门(三)HelloWorld示例的更多相关文章

  1. Storm入门(三)HelloWorld示例

    一.配置开发环境 storm有两种操作模式: 本地模式和远程模式.使用本地模式的时候,你可以在你的本地机器上开发测试你的topology, 一切都在你的本地机器上模拟出来; 用远程模式的时候你提交的t ...

  2. Spring Boot 2.x 快速入门(下)HelloWorld示例详解

    上篇 Spring Boot 2.x 快速入门(上)HelloWorld示例 进行了Sprint Boot的快速入门,以实际的示例代码来练手,总比光看书要强很多嘛,最好的就是边看.边写.边记.边展示. ...

  3. TensorFlow入门,基本介绍,基本概念,计算图,pip安装,helloworld示例,实现简单的神经网络

    TensorFlow入门,基本介绍,基本概念,计算图,pip安装,helloworld示例,实现简单的神经网络

  4. 【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  5. 【原创】NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战

    前言 本文将演示一个iOS客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo.服务端将分别用MINA2和Netty4进行实现,而通信时服务端你只需选其一就行了.同 ...

  6. Netty入门之HelloWorld

    Netty系列入门之HelloWorld(一) 一. 简介 Netty is a NIO client server framework which enables quick and easy de ...

  7. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

    本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...

  8. redis入门(三)

    目录 redis入门(三) 目录 前言 事务 原理 Lua脚本 安装 脚本命令 集群搭建工具 redis-trib.rb redis官方集群搭建 集群横向扩展 故障转移 redis管理 参考文档 re ...

  9. 爬虫入门三 scrapy

    title: 爬虫入门三 scrapy date: 2020-03-14 14:49:00 categories: python tags: crawler scrapy框架入门 1 scrapy简介 ...

随机推荐

  1. pytest进阶之html测试报告

    前言 Pytest系列已经写了几篇文章了,也不知道对多少人有帮助,总之对于我自己来说该掌握的都已经掌握了,那么今天我们再来说说pytest如何生成一个完整的html测试报告,让你在吹牛逼的路上再多一份 ...

  2. 如何用GoldWave批量删除mp3文件开头65秒?

    具体操作如下: 一.打开goldwave--文件--批处理 二.批处理设置:     添加需处理的文件或文件夹(右侧)         1.转换:设置转换格式.         2.处理:       ...

  3. winform 实现类似于TrackBar的自定义滑动条,功能更全

    功能很全,随便列几个 1.可以设置滑块的大小,边框颜色.背景色.形状等等吧 2.可以设置轨道的方向.边框颜色.背景色.阴影等等 ... 效果图: 下载链接https://download.csdn.n ...

  4. python学习——读取染色体长度(七:读取fasta文件)

    读取fasta文件genome_test.fa,并计算染色体总长,同时输出最长染色体编号.序列以及长度 fasta文件genom_test.fa的内容如下: >chr1ATATATATAT> ...

  5. 数据库MySQL(课下作业)

    一.作业要求 下载附件中的world.sql.zip, 参考http://www.cnblogs.com/rocedu/p/6371315.html#SECDB,导入world.sql,提交导入成功截 ...

  6. Json,Gson,Ajax基础知识

    //json 是一种轻量级的文本格式,解析简单,他也是一键值来存,数据与数据的分割是以,来分割 //{} 看到大括号就是一个对象,[]代表集合 ,基本上所有数据的交互都是以json格式来进行传递的 / ...

  7. 【重学计算机】计组D3章:运算方法与运算器

    1. 定点数运算及溢出 定点数加减法:减法化加法,用补码直接相加,忽略进位 溢出:运算结果超出了某种数据类型的表示范围 溢出检测方法:统一思想概括为正正得负或负负得正则溢出,正负或负正不可能溢出 方法 ...

  8. 一致性Hash漫画图解

    一年之前—— 未来两年内,系统预估的总订单数量可达一亿条左右. 按Mysql单表存储500万条记录来算,暂时不必分库,单库30个分表是比较合适的水平分表方案. 于是小灰设计了这样的分表逻辑: 订单表创 ...

  9. 【Vue.js】代码优化:在dom中加一行v-if就可少写一个循环类方法

    [问题描述] 把当前用户的购物车中(cartList),商品(good)选中字段checked = true的商品在订单页面中进行展示出来. [一般做法](两次循环) 首先取出当前用户的购物车列表,循 ...

  10. NTP服务和DNS服务(week3_day3)--技术流ken

    NTP时间服务器 作用:ntp主要是用于对计算机的时间同步管理操作. 时间是对服务器来说是很重要的,一般很多网站都需要读取服务器时间来记录相关信息,如果时间不准,则可能造成很大的影响. 部署安装NTP ...