查看kafka中topic的命令:
创建topic:
kafak命令通信:
生产者:
消费者:
1.创建一个TopologyBuilder拓扑计算,setSpout方法设置Spout,setBolt方法设置Bolt
最后调用createTopology方法返回Storm的Topology对象给Topology方法作为输入参数。
2.继承BaseRichSport【发数据】
常用的方法:
open(Map conf, TopologyContext context, SpoutOutputCollector collector)方法:
初始化方法,只会被调用一次。
conf 配置参数
context: 上下文
collector: 数据发射器
nextTuple()方法:
会产生数据,在生产上肯定是从消息队列中获取数据,这是个死循环,会一直发下去。
declareOutputFields(OutputFieldsDeclarer declarer)方法:
声明输出字段。
3.继承BaseRichBolt或者BaseBasicBolt类【接收数据,处理数据】:
BaseRichBolet在excute()方法执行成功后需要调用OutputCollector.ack(tuple),当失败处理时,执行OutputCollector.fail(tuple);
BaseBasicBolt在excute()方法在执行emit数据时,输入tuple会被自动ack。
实现方法简介:
prepare(Map stormConf, TopologyContext context, OutputCollector collector) :初始化方法,只调用一次。
execute(Tuple input):其实是个死循环,职责:获取Spout发送过来的数据。
declareOutputFields(OutputFieldsDeclarer declarer):声明输出字段
关于接收经纬度的例子:
/**
* 接收Kafka的数据进行处理的BOLT
*/
public class LogProcessBolt extends BaseRichBolt {
private OutputCollector collector;
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector;
}
public void execute(Tuple input) {
try {
byte[] binaryByField = input.getBinaryByField("bytes");
String value = new String(binaryByField);
/**
* 13977777777 116.399466,39.989743 [2018-01-14 11:22:34]
*
* 解析出来日志信息
*/
String[] splits = value.split("\t");
String phone = splits[0];
String[] temp = splits[1].split(",");
String longitude = temp[0];
String latitude = temp[1];
long time = DateUtils.getInstance().getTime(splits[2]);
System.out.println(phone + "," + longitude + "," + latitude + "," + time);
//发射输出
collector.emit(new Values(time, Double.parseDouble(longitude), Double.parseDouble(latitude)));
this.collector.ack(input);
} catch (Exception e) {
this.collector.fail(input);
}
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("time", "longitude", "latitude"));
}
}