Node接入kafka详细教程
kafka的安装与启动
kafka的安装
mac系统下直接使用如下命令安装
brew install kafka
安装完毕后,应用程序目录:
/usr/local/Cellar/kafka/2.0.0
配置文件目录
/usr/local/etc/kafka/
zookeeper配置文件在此目录中,可以看到zookeeper默认端口为2181
kafka启动并发布创建主题
第一步,进入目录程序主目录,先启动zookeeper,再启动kafka
zookeeper-server-start /usr/local/etc/kafka/zookeeper.properties &
kafka-server-start /usr/local/etc/kafka/server.properties &
PS:&为后台运行,另附上停止运行的命令
停止kafka
bin/kafka-server-stop
停止zookeeper
bin/zookeeper-server-stop
第二步,进入bin目录,创建主题topic,使用默认zookeeper以及默认端口即可,分区设置为1个,备份因子1个,主题名称topic-test-one
cd bin
./kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic topic-test-one
通过如下命令可查看所有主题以及主题对应的属性
展示topic
./kafka-topics.sh --list --zookeeper localhost:2181
描述topic
./kafka-topics.sh --describe --zookeeper localhost:2181 --topic topic topic-test-one
Node接入kafka
这里使用的是kafka-node
默认一个分区模式
首先先创建生产者:
var kafka = require('kafka-node'),
Producer = kafka.Producer,
client = new kafka.KafkaClient({kafkaHost: 'localhost:9092'});
/**
* 定义生产类
* partitionerType 定义
* 0:默认模式 只产生数据在第一个分区
* 1:随机分配,在分区个数内,随机产生消息到各分区
* 2:循环分配,在分区个数内,按顺序循环产生消息到各分区
*/
var producerOption = {
requireAcks: 1,
ackTimeoutMs: 100,
partitionerType: 0 //默认为第一个分区
};
var producer = new Producer(client,producerOption);
/**
* TOPIC的创建需要在命令行进行创建,以便指定分区个数以及备份个数
* PS:kafka-node的创建topic不行,不能创建分区
* 产生消息,如果不指定partition
* 则根据 partitionerType 的值来指定发送数据到哪个分区
* 我们创建的topic-test-one只有一个分区,所以只能产生数据到第1个分区(下标0),否则不会生产数据
*/
function getPayloads(){
return [
{topic:"topic-test-one",messages:JSON.stringify({"name":"jack","age":"120"}),partition:0}
];
}
producer.on("ready",function(){
setInterval(function(){
producer.send(getPayloads(),function(err,data){
if(!err){
console.log("send message complete!data:"+JSON.stringify(data),new Date());
}
});
},1000);
});
producer.on('error', function (err) {console.log("send message error!\r\n"+err);})
消费者定义:
const kafka = require('kafka-node');
const client = new kafka.KafkaClient({ kafkaHost: 'localhost:9092' });
/**
* 定义消费参数
*/
var consumerOption = {
groupId:"group-test",
autoCommit: true
};
/**
* 定义consumer,指定从分区0获取数据
*/
const consumer = new kafka.Consumer(client, [
{ topic: 'topic-test-one',partition:0}
],consumerOption);
/**
* 监听消费数据
*/
consumer.on('message', function (message) {
var info = message.value;
console.log("receive info from kafka:"+info,new Date());
});
consumer.on('error', function (message) {
console.log('kafka连接错误,message:'+message);
});
看运行效果:
生产者:
消费者:
随机分区模式
重新创建topic-test-two,分区为2
将生产者producerOption的partitionerType设置为1,以及getPayloads()方法中的partition给删除
var producerOption = {
requireAcks: 1,
ackTimeoutMs: 100,
partitionerType: 1 //随机生产
};
function getPayloads(){
return [
{topic:"topic-test-one",messages:JSON.stringify({"name":"jack","age":"120"})}
];
}
同时创建两个consumer,分别设置取值从partition0和partition1,观察效果
//consumer1 从0个分区获取数据
const consumer = new kafka.Consumer(client, [
{ topic: 'topic-test-two',partition:0}
],consumerOption);
//consumer2 从1个分区获取数据
const consumer = new kafka.Consumer(client, [
{ topic: 'topic-test-two',partition:1}
],consumerOption);
可以看到生产者分别生产分区0和分区1的数据,且具有随机性(箭头指向的第一个数字即为分区)
而消费者分别从0分区和1分区获取数据
从时间上可以看出,他们消费的是不同分区的数据
顺序分区模式
此模式同随机分区模式,只需要设置partitionerType为2即可。