代码运行流程
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);
private FileWriter writer ;
public void execute(Tuple input, BasicOutputCollector collector) {
//获取上一个组件所声明的Field
String text = input.getStringByField("write");
try {
if(writer == null){
if(System.getProperty("os.name").equals("Windows 10")){
writer = new FileWriter("D:\\099_test\\" + this);
} else if(System.getProperty("os.name").equals("Windows 8.1")){
writer = new FileWriter("D:\\099_test\\" + this);
} else if(System.getProperty("os.name").equals("Windows 7")){
writer = new FileWriter("D:\\099_test\\" + this);
} else if(System.getProperty("os.name").equals("Linux")){
System.out.println("----:" + System.getProperty("os.name"));
writer = new FileWriter("/usr/local/temp/" + this);
}
}
log.info("【write】: 写入文件");
writer.write(text);
writer.write("\n");
writer.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
}
}
public class PWTopology2 {
public static void main(String[] args) throws Exception {
Config cfg = new Config();
cfg.setNumWorkers(2);//设置使用俩个工作进程
cfg.setDebug(false);
TopologyBuilder builder = new TopologyBuilder();
//设置sqout的并行度和任务数(产生2个执行器和俩个任务)
builder.setSpout("spout", new PWSpout(), 2);//.setNumTasks(2);
//设置bolt的并行度和任务数:(产生2个执行器和4个任务)
builder.setBolt("print-bolt", new PrintBolt(), 2).shuffleGrouping("spout").setNumTasks(4);
//设置bolt的并行度和任务数:(产生6个执行器和6个任务)
builder.setBolt("write-bolt", new WriteBolt(), 6).shuffleGrouping("print-bolt");
//1 本地模式
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("top2", cfg, builder.createTopology());
Thread.sleep(10000000);
cluster.killTopology("top2");
cluster.shutdown();
//2 集群模式
// StormSubmitter.submitTopology("top2", cfg, builder.createTopology());
}
}
首先设置了两个工作进程(也就是两个2个jvm)
然后设置了spout的并行为2(产生2个执行器和2个任务)
第一个bolt的并行度为2并且指定任务数为4(产生2个执行器和4个任务)
第二个bolt的并行度为6(产生6个执行器和6个任务)
因此:该 Topology 程序共有两个工作进程(worker),2+2+6=10个执行器(executor),2+4+6=12个任务(task)。每个工作进程可以领取到12/2=6个任务。默认情况下一个执行器执行一个任务,但是如果指定了任务的数目,则任务会平均分配到执行器中。
代码运行结果:
WriteBolt 在每台机子被 new 了有3个对象。即有6个任务。(因为直接用 WriteBolt 的对象做文件名,所以产生多少个文件,就可以确定生成了即个对象)。