kafkaspout以及kafkabolt的最简实例
import
java.util.HashMap;
import
java.util.Map;
import
backtype.storm.Config;
import
backtype.storm.LocalCluster;
//import backtype.storm.LocalCluster;
import
backtype.storm.StormSubmitter;
import
backtype.storm.spout.SchemeAsMultiScheme;
import
backtype.storm.topology.TopologyBuilder;
import
storm.kafka.BrokerHosts;
import
storm.kafka.KafkaSpout;
import
storm.kafka.SpoutConfig;
import
storm.kafka.ZkHosts;
import
storm.kafka.bolt.KafkaBolt;
public
class
topology {
public
static
void
main(String [] args)
throws
Exception{
//配置zookeeper 主机:端口号
BrokerHosts brokerHosts =
new
ZkHosts(
"110.64.76.130:2181,110.64.76.131:2181,110.64.76.132:2181"
);
//接收消息队列的主题
String topic=
"recommend"
;
//zookeeper设置文件中的配置,如果zookeeper配置文件中设置为主机名:端口号 ,该项为空
String
zkRoot
=
""
;
//任意
String spoutId=
"zhou"
;
SpoutConfig spoutConfig=
new
SpoutConfig(brokerHosts, topic, zkRoot, spoutId);
//设置如何处理kafka消息队列输入流
spoutConfig.scheme=
new
SchemeAsMultiScheme(
new
MessageScheme());
Config conf=
new
Config();
//不输出调试信息
conf.setDebug(
false
);
//设置一个spout task中处于pending状态的最大的tuples数量
conf.put(Config.TOPOLOGY_MAX_SPOUT_PENDING,
1
);
Map<String, String> map=
new
HashMap<String,String>();
// 配置Kafka broker地址
map.put(
"metadata.broker.list"
,
"master:9092,slave1:9092,slave2:9092"
);
// serializer.class为消息的序列化类
map.put(
"serializer.class"
,
"kafka.serializer.StringEncoder"
);
conf.put(
"kafka.broker.properties"
, map);
// 配置KafkaBolt生成的topic
conf.put(
"topic"
,
"receiver"
);
TopologyBuilder builder =
new
TopologyBuilder();
builder.setSpout(
"spout"
,
new
KafkaSpout(spoutConfig),
1
);
builder.setBolt(
"bolt1"
,
new
QueryBolt(),
1
).setNumTasks(
1
).shuffleGrouping(
"spout"
);
builder.setBolt(
"bolt2"
,
new
KafkaBolt<String, String>(),
1
).setNumTasks(
1
).shuffleGrouping(
"bolt1"
);
if
(args.length==
0
){
LocalCluster cluster =
new
LocalCluster();
//提交本地集群
cluster.submitTopology(
"test"
, conf, builder.createTopology());
//等待6s之后关闭集群
Thread.sleep(
6000
);
//关闭集群
cluster.shutdown();
}
StormSubmitter.submitTopology(
"test"
, conf, builder.createTopology());
}
}
然后是MessageScheme.java
import
java.io.UnsupportedEncodingException;
import
java.util.List;
import
org.slf4j.Logger;
import
org.slf4j.LoggerFactory;
import
backtype.storm.spout.Scheme;
import
backtype.storm.tuple.Fields;
import
backtype.storm.tuple.Values;
public
class
MessageScheme
implements
Scheme {
private
static
final
Logger LOGGER = LoggerFactory.getLogger(MessageScheme.
class
);
public
List<Object> deserialize(
byte
[] ser) {
try
{
//从kafka中读取的值直接序列化为UTF-8的str
String mString=
new
String(ser,
"UTF-8"
);
return
new
Values(mString);
}
catch
(UnsupportedEncodingException e) {
// TODO Auto-generated catch block
LOGGER.error(
"Cannot parse the provided message"
);
}
return
null
;
}
public
Fields getOutputFields() {
// TODO Auto-generated method stub
return
new
Fields(
"msg"
);
}
}
最后是QueryBolt.java
import
java.io.FileNotFoundException;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.PrintStream;
import
java.util.ArrayList;
import
java.util.List;
import
java.util.Map;
import
java.util.Vector;
import
backtype.storm.task.OutputCollector;
import
backtype.storm.task.TopologyContext;
import
backtype.storm.topology.IRichBolt;
import
backtype.storm.topology.OutputFieldsDeclarer;
import
backtype.storm.tuple.Fields;
import
backtype.storm.tuple.Tuple;
import
backtype.storm.tuple.Values;
public
class
QueryBolt
implements
IRichBolt {
List<String> list;
OutputCollector collector;
public
void
prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
list=
new
ArrayList<String>();
this
.collector=collector;
}
public
void
execute(Tuple input) {
// TODO Auto-generated method stub
String str=(String) input.getValue(
0
);
//将str加入到list
list.add(str);
//发送ack
collector.ack(input);
//发送该str
collector.emit(
new
Values(str));
}
public
void
cleanup() {
//topology被killed时调用
//将list的值写入到文件
try
{
PrintStream p=
new
PrintStream(outputStream);
p.println(
"begin!"
);
p.println(list.size());
for
(String tmp:list){
p.println(tmp);
}
p.println(
"end!"
);
try
{
p.close();
outputStream.close();
}
catch
(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch
(FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public
void
declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(
new
Fields(
"message"
));
}
public
Map<String, Object> getComponentConfiguration() {
// TODO Auto-generated method stub
return
null
;
}
}
问题1:zkRoot如何设置?非常重要,设置错误无法正确从kafka消息队列中取出数据。
SpoutConfig继承自KafkaConfig。由于SpoutConfig和KafkaConfig所有的instance field全是
public
, 因此在使用构造方法后,可以直接设置各个域的值。
public
class
SpoutConfig
extends
KafkaConfig
implements
Serializable {
public
List<String> zkServers =
null
;
//记录Spout读取进度所用的zookeeper的host
public
Integer zkPort =
null
;
//记录进度用的zookeeper的端口
public
String zkRoot =
null
;
//进度信息记录于zookeeper的哪个路径下
public
String id =
null
;
//进度记录的id,想要一个新的Spout读取之前的记录,应把它的id设为跟之前的一样。
public
long
stateUpdateIntervalMs =
2000
;
//用于metrics,多久更新一次状态。
public
SpoutConfig(BrokerHosts hosts, String topic, String zkRoot, String id) {
super
(hosts, topic);
this
.zkRoot = zkRoot;
this
.id = id;
}
}
public
class
KafkaConfig
implements
Serializable {
public
final
BrokerHosts hosts;
//用以获取Kafka broker和partition的信息
public
final
String topic;
//从哪个topic读取消息
public
final
String clientId;
// SimpleConsumer所用的client id
public
int
fetchSizeBytes =
1024
*
1024
;
//发给Kafka的每个FetchRequest中,用此指定想要的response中总的消息的大小
public
int
socketTimeoutMs =
10000
;
//与Kafka broker的连接的socket超时时间
public
int
fetchMaxWait =
10000
;
//当服务器没有新消息时,消费者会等待这些时间
public
int
bufferSizeBytes =
1024
*
1024
;
//SimpleConsumer所使用的SocketChannel的读缓冲区大小
public
MultiScheme scheme =
new
RawMultiScheme();
//从Kafka中取出的byte[],该如何反序列化
public
boolean
forceFromStart =
false
;
//是否强制从Kafka中offset最小的开始读起
public
long
startOffsetTime = kafka.api.OffsetRequest.EarliestTime();
//从何时的offset时间开始读,默认为最旧的offset
public
long
maxOffsetBehind =
100000
;
//KafkaSpout读取的进度与目标进度相差多少,相差太多,Spout会丢弃中间的消息
public
boolean
useStartOffsetTimeIfOffsetOutOfRange =
true
;
//如果所请求的offset对应的消息在Kafka中不存在,是否使用startOffsetTime
public
int
metricsTimeBucketSizeInSecs =
60
;
//多长时间统计一次metrics
public
KafkaConfig(BrokerHosts hosts, String topic) {
this
(hosts, topic, kafka.api.OffsetRequest.DefaultClientId());
}
public
KafkaConfig(BrokerHosts hosts, String topic, String clientId) {
this
.hosts = hosts;
this
.topic = topic;
this
.clientId = clientId;
}
}
kafkaspout以及kafkabolt的最简实例的更多相关文章
- 最简实例演示asp.net5中用户认证和授权(4)
上篇: 最简实例演示asp.net5中用户认证和授权(3) 上面我们把自定义认证和授权的相关的最小基础类和要实现的接口都实现了,下面就是如何来进行认证和授权的配置. 首先我们要告诉系统,我们的用户和角 ...
- 最简实例演示asp.net5中用户认证和授权(3)
上接: 最简实例演示asp.net5中用户认证和授权(2) 在实现了角色的各种管理接口后,下一步就是实现对用户的管理,对用户管理的接口相对多一些,必须要实现的有如下三个: 1 public inter ...
- 最简实例演示asp.net5中用户认证和授权(2)
上接最简实例演示asp.net5中用户认证和授权(1) 基础类建立好后,下一步就要创建对基础类进行操作的类了,也就是实现基础类的增删改查(听起来不太高大上),当然,为了使用asp.net5的认证机制, ...
- 最简实例演示asp.net5中用户认证和授权(1)
asp.net5中,关于用户的认证和授权提供了非常丰富的功能,如果结合ef7的话,可以自动生成相关的数据库表,调用也很方便. 但是,要理解这么一大堆关于认证授权的类,或者想按照自己项目的特定要求对认证 ...
- 最简实例说明wait、notify、notifyAll的使用方法
wait().notify().notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态. 这三个方法最终调用的都是jvm级的native方法.随着jvm运行平台的不同可能有些 ...
- inheritprototype原型继承封装及综合继承最简实例
1.inheritprototype.js ;(function(){ var s = { inheritObject:function(o){//对象继承封装 ...
- Express极简实例
假设已创建一个Express工程,否则请参考express工程环境准备 修改app.js var express = require('express'); var app = express(); ...
- Servlet(1):基础概念/最简实例
Servlet 生命周期(1) init()方法初始化Servlet对象 它在第一次创建Servlet时被调用,在后续每次不同用户请求时不再调用.(2) service()方法来处理客户端的请求 ...
- kafka主题offset各种需求修改方法
简要:开发中,常常因为需要我们要认为修改消费者实例对kafka某个主题消费的偏移量.具体如何修改?为什么可行?其实很容易,有时候只要我们换一种方式思考,如果我自己实现kafka消费者,我该如何让我们的 ...
随机推荐
- 表达式语言--在MVC中应用表达式语言
之前讲解的MVC设计模式中一直有DAO存在,而且所有的对象都保存在VO之中,那么这时如果将一个VO传递到JSP文件中,那么JSP需要导入VO包,如果使用表达式语言的话,导入VO包就没有任何意义了. V ...
- textbox文本键盘全选
private void textBox1_KeyDown(object sender, KeyEventArgs e) { if (e.Modifiers == ...
- js 鼠标事件
<html><head lang="en"> <meta charset="UTF-8"> <title>< ...
- 填写信息的文章区域text_area
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>& ...
- linux操作命令实验
实验内容:文件操作与用户操作实验 实验设备(环境):电脑.Vmware WorkStation 实验步骤: 一.创建新用户bob 目的:练习useradd命令 二.为新用户bob设置口令 目的:练习p ...
- PAT (Advanced Level) 1045. Favorite Color Stripe (30)
最长公共子序列变形. #include<iostream> #include<cstring> #include<cmath> #include<algori ...
- Django之路:简介以及环境
(sudo) pip install Django 或者 (sudo) pip install Django==1.6.10 或者 pip install Django==1.7.6 Windows ...
- BLDC(无刷直流电机)应用相关
1.基于XC866的直流无刷电机简易正弦波控制 http://blog.gkong.com/hushunlin_219521.ashx 2.无刷直流电机的PWM调制方式介绍 http://blog.g ...
- javascript 中 function bind()
Function bind() and currying <%-- All JavaScript functions have a method called bind that binds t ...
- 函数之局部变量和使用global语句
局部变量当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的.这称为变量的 作用域 .所有变量的作用域是它们被定义的块,从它们的名称被定义 ...