一、kafka集群搭建  

  至于kafka是什么我都不多做介绍了,网上写的已经非常详尽了。

(没安装java环境的需要先安装 yum -y install java-1.8.0-openjdk*)

1. 下载zookeeper  https://zookeeper.apache.org/releases.html

2. 下载kafka http://kafka.apache.org/downloads

3. 启动zookeeper集群(我的示例是3台机器,后面的kafka也一样,这里就以1台代指3台,当然你也可以只开1台)

  1)配置zookeeper。 修改复制一份 zookeeper-3.4.13/conf/zoo_sample.cfg 改名成zoo.cfg。修改以下几个参数,改成适合自己机器的。

  dataDir=/home/test/zookeeper/data
  dataLogDir=/home/test/zookeeper/log
  server.=10.22.1.1::
  server.=10.22.1.2::
  server.=10.22.1.3::

  2) 创建myid文件,确定机器编号。分别在3台机器的/home/test/zookeeper/data目录执行分别执行命令 echo 1 > myid(注意ip为10.22.1.2把1改成2,见上面的配置)

  3) 启动zookeeper集群。分别进入目录zookeeper-3.4.13/bin 执行 sh zkServer.sh start

4. 启动kafka集群

  1) 配置kafka。进入kafka_2.11-2.2.0/config。复制3份,分别为server1.properties,server2.properties,server3.properties。修改以下几项(注意对应的机器id)

log.dirs和zookeeper.connect 是一样的。broker.id和listeners分别填对应的id和ip
broker.id=
listeners=PLAINTEXT://10.22.1.1:9092
log.dirs=/home/test/kafka/log
zookeeper.connect=10.22.1.1:,10.22.1.2:,10.22.1.3:

  2) 启动kafka集群。分别进入kafka_2.11-2.2.0/bin目录,分别执行sh kafka-server-start.sh ../config/server1.properties (第2台用server2.properties配置文件)

 

二、Golang生产者和消费者

  目前比较流行的golang版的kafka客户端库有两个:

  1. https://github.com/Shopify/sarama

  2. https://github.com/confluentinc/confluent-kafka-go

  至于谁好谁坏自己去分辨,我用的是第1个,star比较多的。

1. kafka生产者代码

  这里有2点要说明:

  1)  config.Producer.Partitioner = sarama.NewRandomPartitioner,我分partition用的是随机,如果你想稳定分paritition的话可以自定义,还有轮询和hash方式

  2) 我的topic是走的外部配置,可以根据自己的需求修改

// Package kafka_producer kafka 生产者的包装
package kafka_producer import (
"github.com/Shopify/sarama"
"strings"
"sync"
"time" "github.com/alecthomas/log4go"
) // Config 配置
type Config struct {
Topic string `xml:"topic"`
Broker string `xml:"broker"`
Frequency int `xml:"frequency"`
MaxMessage int `xml:"max_message"`
} type Producer struct {
producer sarama.AsyncProducer topic string
msgQ chan *sarama.ProducerMessage
wg sync.WaitGroup
closeChan chan struct{}
} // NewProducer 构造KafkaProducer
func NewProducer(cfg *Config) (*Producer, error) { config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.NoResponse // Only wait for the leader to ack
config.Producer.Compression = sarama.CompressionSnappy // Compress messages
config.Producer.Flush.Frequency = time.Duration(cfg.Frequency) * time.Millisecond // Flush batches every 500ms
config.Producer.Partitioner = sarama.NewRandomPartitioner p, err := sarama.NewAsyncProducer(strings.Split(cfg.Broker, ","), config)
if err != nil {
return nil, err
}
ret := &Producer{
producer: p,
topic: cfg.Topic,
msgQ: make(chan *sarama.ProducerMessage, cfg.MaxMessage),
closeChan: make(chan struct{}),
} return ret, nil
} // Run 运行
func (p *Producer) Run() { p.wg.Add()
go func() {
defer p.wg.Done() LOOP:
for {
select {
case m := <-p.msgQ:
p.producer.Input() <- m
case err := <-p.producer.Errors():
if nil != err && nil != err.Msg {
l4g.Error("[producer] err=[%s] topic=[%s] key=[%s] val=[%s]", err.Error(), err.Msg.Topic, err.Msg.Key, err.Msg.Value)
}
case <-p.closeChan:
break LOOP
} }
}() for hasTask := true; hasTask; {
select {
case m := <-p.msgQ:
p.producer.Input() <- m
default:
hasTask = false
}
} } // Close 关闭
func (p *Producer) Close() error {
close(p.closeChan)
l4g.Warn("[producer] is quiting")
p.wg.Wait()
l4g.Warn("[producer] quit over") return p.producer.Close()
} // Log 发送log
func (p *Producer) Log(key string, val string) {
msg := &sarama.ProducerMessage{
Topic: p.topic,
Key: sarama.StringEncoder(key),
Value: sarama.StringEncoder(val),
} select {
case p.msgQ <- msg:
return
default:
l4g.Error("[producer] err=[msgQ is full] key=[%s] val=[%s]", msg.Key, msg.Value)
}
}

2. kafka消费者

  几点说明:

  1) kafka一定要选用支持集群的版本

  2) 里面带了创建topic,删除topic,打印topic的工具

  3) replication是外面配置的

  4) 开多个consumer需要在创建topic时设置多个partition。官方的示例当开多个consumer的时候会崩溃,我这个版本不会,我给官方提交了一个PR,还不知道有没有采用

// Package main Kafka消费者
package main import (
"context"
"encoding/xml"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"os/signal"
"runtime"
"strings"
"syscall"
"time" "github.com/Shopify/sarama"
"github.com/alecthomas/log4go"
) // Consumer Consumer配置
type ConsumerConfig struct {
Topic []string `xml:"topic"`
Broker string `xml:"broker"`
Partition int32 `xml:"partition"`
Replication int16 `xml:"replication"`
Group string `xml:"group"`
Version string `xml:"version"`
} var (
configFile = "" // 配置路径
initTopic = false
listTopic = false
delTopic = ""
cfg = &Config{}
) // Config 配置
type Config struct {
Consumer ConsumerConfig `xml:"consumer"`
} func init() {
flag.StringVar(&configFile, "config", "../config/consumer.xml", "config file ")
flag.BoolVar(&initTopic, "init", initTopic, "create topic")
flag.BoolVar(&listTopic, "list", listTopic, "list topic")
flag.StringVar(&delTopic, "del", delTopic, "delete topic") } func main() { runtime.GOMAXPROCS(runtime.NumCPU()) defer func() {
time.Sleep(time.Second)
log4go.Warn("[main] consumer quit over!")
log4go.Global.Close()
}() contents, _ := ioutil.ReadFile(configFile)
xml.Unmarshal(contents, cfg) // sarama的logger
sarama.Logger = log.New(os.Stdout, fmt.Sprintf("[%s]", "consumer"), log.LstdFlags) // 指定kafka版本,一定要支持kafka集群
version, err := sarama.ParseKafkaVersion(cfg.Consumer.Version)
if err != nil {
panic(err)
}
config := sarama.NewConfig()
config.Version = version
config.Consumer.Offsets.Initial = sarama.OffsetOldest // 工具
if tool(cfg, config) {
return
} // kafka consumer client
ctx, cancel := context.WithCancel(context.Background())
client, err := sarama.NewConsumerGroup(strings.Split(cfg.Consumer.Broker, ","), cfg.Consumer.Group, config)
if err != nil {
panic(err)
} consumer := Consumer{}
go func() {
for {
err := client.Consume(ctx, cfg.Consumer.Topic, &consumer)
if err != nil {
log4go.Error("[main] client.Consume error=[%s]", err.Error())
// 5秒后重试
time.Sleep(time.Second * )
}
}
}() // os signal
sigterm := make(chan os.Signal, )
signal.Notify(sigterm, syscall.SIGINT, syscall.SIGTERM) <-sigterm cancel()
err = client.Close()
if err != nil {
panic(err)
} log4go.Info("[main] consumer is quiting")
} func tool(cfg *Config, config *sarama.Config) bool {
if initTopic || listTopic || len(delTopic) > {
ca, err := sarama.NewClusterAdmin(strings.Split(cfg.Consumer.Broker, ","), config)
if nil != err {
panic(err)
} if len(delTopic) > { // 删除Topic
if err := ca.DeleteTopic(delTopic); nil != err {
panic(err)
}
log4go.Info("delete ok topic=[%s]\n", delTopic)
} else if initTopic { // 初始化Topic
if detail, err := ca.ListTopics(); nil != err {
panic(err)
} else {
for _, v := range cfg.Consumer.Topic {
if d, ok := detail[v]; ok {
if cfg.Consumer.Partition > d.NumPartitions {
if err := ca.CreatePartitions(v, cfg.Consumer.Partition, nil, false); nil != err {
panic(err)
}
log4go.Info("alter topic ok", v, cfg.Consumer.Partition)
} } else {
if err := ca.CreateTopic(v, &sarama.TopicDetail{NumPartitions: cfg.Consumer.Partition, ReplicationFactor: cfg.Consumer.Replication}, false); nil != err {
panic(err)
}
log4go.Info("create topic ok", v)
}
}
}
} // 显示Topic列表
if detail, err := ca.ListTopics(); nil != err {
log4go.Info("ListTopics error", err)
} else {
for k := range detail {
log4go.Info("[%s] %+v", k, detail[k])
}
} if err := ca.Close(); nil != err {
panic(err)
} return true
}
return false
} type Consumer struct {
} func (consumer *Consumer) Setup(s sarama.ConsumerGroupSession) error {
return nil
} func (consumer *Consumer) Cleanup(s sarama.ConsumerGroupSession) error {
return nil
} func (consumer *Consumer) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
for message := range claim.Messages() {
key := string(message.Key)
val := string(message.Value)
log4go.Info("%s-%s", key, val)
session.MarkMessage(message, "")
} return nil
}

[Golang] kafka集群搭建和golang版生产者和消费者的更多相关文章

  1. kafka集群搭建及结合springboot使用

    1.场景描述 因kafka以前用的不多,只往topic中写入和读取过数据,这次刚好又要用到,记录下kafka集群搭建及结合springboot使用. 2. 解决方案 2.1 简单介绍 (一)关于kaf ...

  2. kafka集群搭建和使用Java写kafka生产者消费者

    1 kafka集群搭建 1.zookeeper集群  搭建在110, 111,112 2.kafka使用3个节点110, 111,112 修改配置文件config/server.properties ...

  3. Kafka【第一篇】Kafka集群搭建

    Kafka初识 1.Kafka使用背景 在我们大量使用分布式数据库.分布式计算集群的时候,是否会遇到这样的一些问题: 我们想分析下用户行为(pageviews),以便我们设计出更好的广告位 我想对用户 ...

  4. kafka学习(三)-kafka集群搭建

    kafka集群搭建 下面简单的介绍一下kafka的集群搭建,单个kafka的安装更简单,下面以集群搭建为例子. 我们设置并部署有三个节点的 kafka 集合体,必须在每个节点上遵循下面的步骤来启动 k ...

  5. Zookeeper + Kafka 集群搭建

    第一步:准备 1. 操作系统 CentOS-7-x86_64-Everything-1511 2. 安装包 kafka_2.12-0.10.2.0.tgz zookeeper-3.4.9.tar.gz ...

  6. 大数据 --> Kafka集群搭建

    Kafka集群搭建 下面是以三台机器搭建为例,(扩展到4台以上一样,修改下配置文件即可) 1.下载kafka http://apache.fayea.com/kafka/0.9.0.1/ ,拷贝到三台 ...

  7. 消息队列kafka集群搭建

    linux系统kafka集群搭建(3个节点192.168.204.128.192.168.204.129.192.168.204.130)    本篇文章kafka集群采用外部zookeeper,没采 ...

  8. zookeeper及kafka集群搭建

    zookeeper及kafka集群搭建 1.有关zookeeper的介绍可参考:http://www.cnblogs.com/wuxl360/p/5817471.html 2.zookeeper安装 ...

  9. 【转】kafka集群搭建

    转:http://www.cnblogs.com/luotianshuai/p/5206662.html Kafka初识 1.Kafka使用背景 在我们大量使用分布式数据库.分布式计算集群的时候,是否 ...

随机推荐

  1. JDK提供的几种线程池比较

    JDK提供的几种线程池 newFixedThreadPool创建一个指定工作线程数量的线程池.每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中. ...

  2. 推荐一款jQueryajax插件(Ajaxify jQuery )

    推荐一款jQueryajax插件(Ajaxify jQuery )       此插件相当强悍,但最后一个版本是在2008年,作者很久没更新了,我在寻找了好多关羽ajax的工具,没有发现比这个更灵活的 ...

  3. Creating a NuGet Package in 7 easy steps - Plus using NuGet to integrate ASP.NET MVC 3 into existing Web Forms applications

    UPDATE: Check out my follow up post where I remove the need for editing the Global.asax.cs and show ...

  4. 最课程阶段大作业06:U度节能平台控制系统

    除了互联网项目,当今社会还有一个概念非常流行,那就是:物联网.什么是物联网?物联网是通过传感设备,按约定的协议,把任意物品与互联网相连接,进行信息交换和通信,以实现智能化识别.定位.跟踪.监控和管理的 ...

  5. 超过 130 个你需要了解的 vim 命令

    从 1970 年开始,vi 和 vim 就成为了程序员最喜爱的文本编辑器之一.5年前,我写了一个问自己名为 “每个程序员都应该知道的 100 个 vim 命令” 这次算是之前那篇文章的改进版,希望你会 ...

  6. jvm理论-字节码指令案例

    案例1 public class Demo { public int calc(){ int a=100; int b=200; int c=300; return(a+b)*c; } public ...

  7. shell编程学习笔记(六):cat命令的使用

    这一篇不是讲shell编程的,专门讲cat命令.shell编程书用到了这个cat命令,顺便说一下cat命令. cat命令有多种用法,我一一来列举(以下蓝色字体部分为Linux命令,红色字体的内容为输出 ...

  8. PHP知识梳理

      前端 HTML.CSS. JS(DOM操作.事件操作).Jquery(选择器.属性/值操作.事件操作).ajax PHP基础 变量(类型.类型转换) 常量(系统.自定义) 运算(算术.字符串.赋值 ...

  9. protobuf 动态创建

    https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.html https://originlee.com/2015/03/14/ana ...

  10. GDAL指定自定义的金字塔目录

    缘起 对于一般的遥感影像文件,金字塔文件默认都是与影像文件放在同一个目录下,金字塔文件名一般与源影像文件名相同,但后缀名不同.或者金字塔内建于影像内部,但这不是这里所涉及的. 在使用ArcGIS桌面版 ...