一、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。修改以下几个参数,改成适合自己机器的。

  1.   dataDir=/home/test/zookeeper/data
  2.   dataLogDir=/home/test/zookeeper/log
  3.   server.=10.22.1.1::
  4.   server.=10.22.1.2::
  5.   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)

  1. log.dirszookeeper.connect 是一样的。broker.idlisteners分别填对应的idip
  1. broker.id=
  2. listeners=PLAINTEXT://10.22.1.1:9092
  3. log.dirs=/home/test/kafka/log
  4. 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是走的外部配置,可以根据自己的需求修改

  1. // Package kafka_producer kafka 生产者的包装
  2. package kafka_producer
  3.  
  4. import (
  5. "github.com/Shopify/sarama"
  6. "strings"
  7. "sync"
  8. "time"
  9.  
  10. "github.com/alecthomas/log4go"
  11. )
  12.  
  13. // Config 配置
  14. type Config struct {
  15. Topic string `xml:"topic"`
  16. Broker string `xml:"broker"`
  17. Frequency int `xml:"frequency"`
  18. MaxMessage int `xml:"max_message"`
  19. }
  20.  
  21. type Producer struct {
  22. producer sarama.AsyncProducer
  23.  
  24. topic string
  25. msgQ chan *sarama.ProducerMessage
  26. wg sync.WaitGroup
  27. closeChan chan struct{}
  28. }
  29.  
  30. // NewProducer 构造KafkaProducer
  31. func NewProducer(cfg *Config) (*Producer, error) {
  32.  
  33. config := sarama.NewConfig()
  34. config.Producer.RequiredAcks = sarama.NoResponse // Only wait for the leader to ack
  35. config.Producer.Compression = sarama.CompressionSnappy // Compress messages
  36. config.Producer.Flush.Frequency = time.Duration(cfg.Frequency) * time.Millisecond // Flush batches every 500ms
  37. config.Producer.Partitioner = sarama.NewRandomPartitioner
  38.  
  39. p, err := sarama.NewAsyncProducer(strings.Split(cfg.Broker, ","), config)
  40. if err != nil {
  41. return nil, err
  42. }
  43. ret := &Producer{
  44. producer: p,
  45. topic: cfg.Topic,
  46. msgQ: make(chan *sarama.ProducerMessage, cfg.MaxMessage),
  47. closeChan: make(chan struct{}),
  48. }
  49.  
  50. return ret, nil
  51. }
  52.  
  53. // Run 运行
  54. func (p *Producer) Run() {
  55.  
  56. p.wg.Add()
  57. go func() {
  58. defer p.wg.Done()
  59.  
  60. LOOP:
  61. for {
  62. select {
  63. case m := <-p.msgQ:
  64. p.producer.Input() <- m
  65. case err := <-p.producer.Errors():
  66. if nil != err && nil != err.Msg {
  67. l4g.Error("[producer] err=[%s] topic=[%s] key=[%s] val=[%s]", err.Error(), err.Msg.Topic, err.Msg.Key, err.Msg.Value)
  68. }
  69. case <-p.closeChan:
  70. break LOOP
  71. }
  72.  
  73. }
  74. }()
  75.  
  76. for hasTask := true; hasTask; {
  77. select {
  78. case m := <-p.msgQ:
  79. p.producer.Input() <- m
  80. default:
  81. hasTask = false
  82. }
  83. }
  84.  
  85. }
  86.  
  87. // Close 关闭
  88. func (p *Producer) Close() error {
  89. close(p.closeChan)
  90. l4g.Warn("[producer] is quiting")
  91. p.wg.Wait()
  92. l4g.Warn("[producer] quit over")
  93.  
  94. return p.producer.Close()
  95. }
  96.  
  97. // Log 发送log
  98. func (p *Producer) Log(key string, val string) {
  99. msg := &sarama.ProducerMessage{
  100. Topic: p.topic,
  101. Key: sarama.StringEncoder(key),
  102. Value: sarama.StringEncoder(val),
  103. }
  104.  
  105. select {
  106. case p.msgQ <- msg:
  107. return
  108. default:
  109. l4g.Error("[producer] err=[msgQ is full] key=[%s] val=[%s]", msg.Key, msg.Value)
  110. }
  111. }

2. kafka消费者

  几点说明:

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

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

  3) replication是外面配置的

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

  1. // Package main Kafka消费者
  2. package main
  3.  
  4. import (
  5. "context"
  6. "encoding/xml"
  7. "flag"
  8. "fmt"
  9. "io/ioutil"
  10. "log"
  11. "os"
  12. "os/signal"
  13. "runtime"
  14. "strings"
  15. "syscall"
  16. "time"
  17.  
  18. "github.com/Shopify/sarama"
  19. "github.com/alecthomas/log4go"
  20. )
  21.  
  22. // Consumer Consumer配置
  23. type ConsumerConfig struct {
  24. Topic []string `xml:"topic"`
  25. Broker string `xml:"broker"`
  26. Partition int32 `xml:"partition"`
  27. Replication int16 `xml:"replication"`
  28. Group string `xml:"group"`
  29. Version string `xml:"version"`
  30. }
  31.  
  32. var (
  33. configFile = "" // 配置路径
  34. initTopic = false
  35. listTopic = false
  36. delTopic = ""
  37. cfg = &Config{}
  38. )
  39.  
  40. // Config 配置
  41. type Config struct {
  42. Consumer ConsumerConfig `xml:"consumer"`
  43. }
  44.  
  45. func init() {
  46. flag.StringVar(&configFile, "config", "../config/consumer.xml", "config file ")
  47. flag.BoolVar(&initTopic, "init", initTopic, "create topic")
  48. flag.BoolVar(&listTopic, "list", listTopic, "list topic")
  49. flag.StringVar(&delTopic, "del", delTopic, "delete topic")
  50.  
  51. }
  52.  
  53. func main() {
  54.  
  55. runtime.GOMAXPROCS(runtime.NumCPU())
  56.  
  57. defer func() {
  58. time.Sleep(time.Second)
  59. log4go.Warn("[main] consumer quit over!")
  60. log4go.Global.Close()
  61. }()
  62.  
  63. contents, _ := ioutil.ReadFile(configFile)
  64. xml.Unmarshal(contents, cfg)
  65.  
  66. // sarama的logger
  67. sarama.Logger = log.New(os.Stdout, fmt.Sprintf("[%s]", "consumer"), log.LstdFlags)
  68.  
  69. // 指定kafka版本,一定要支持kafka集群
  70. version, err := sarama.ParseKafkaVersion(cfg.Consumer.Version)
  71. if err != nil {
  72. panic(err)
  73. }
  74. config := sarama.NewConfig()
  75. config.Version = version
  76. config.Consumer.Offsets.Initial = sarama.OffsetOldest
  77.  
  78. // 工具
  79. if tool(cfg, config) {
  80. return
  81. }
  82.  
  83. // kafka consumer client
  84. ctx, cancel := context.WithCancel(context.Background())
  85. client, err := sarama.NewConsumerGroup(strings.Split(cfg.Consumer.Broker, ","), cfg.Consumer.Group, config)
  86. if err != nil {
  87. panic(err)
  88. }
  89.  
  90. consumer := Consumer{}
  91. go func() {
  92. for {
  93. err := client.Consume(ctx, cfg.Consumer.Topic, &consumer)
  94. if err != nil {
  95. log4go.Error("[main] client.Consume error=[%s]", err.Error())
  96. // 5秒后重试
  97. time.Sleep(time.Second * )
  98. }
  99. }
  100. }()
  101.  
  102. // os signal
  103. sigterm := make(chan os.Signal, )
  104. signal.Notify(sigterm, syscall.SIGINT, syscall.SIGTERM)
  105.  
  106. <-sigterm
  107.  
  108. cancel()
  109. err = client.Close()
  110. if err != nil {
  111. panic(err)
  112. }
  113.  
  114. log4go.Info("[main] consumer is quiting")
  115. }
  116.  
  117. func tool(cfg *Config, config *sarama.Config) bool {
  118. if initTopic || listTopic || len(delTopic) > {
  119. ca, err := sarama.NewClusterAdmin(strings.Split(cfg.Consumer.Broker, ","), config)
  120. if nil != err {
  121. panic(err)
  122. }
  123.  
  124. if len(delTopic) > { // 删除Topic
  125. if err := ca.DeleteTopic(delTopic); nil != err {
  126. panic(err)
  127. }
  128. log4go.Info("delete ok topic=[%s]\n", delTopic)
  129. } else if initTopic { // 初始化Topic
  130. if detail, err := ca.ListTopics(); nil != err {
  131. panic(err)
  132. } else {
  133. for _, v := range cfg.Consumer.Topic {
  134. if d, ok := detail[v]; ok {
  135. if cfg.Consumer.Partition > d.NumPartitions {
  136. if err := ca.CreatePartitions(v, cfg.Consumer.Partition, nil, false); nil != err {
  137. panic(err)
  138. }
  139. log4go.Info("alter topic ok", v, cfg.Consumer.Partition)
  140. }
  141.  
  142. } else {
  143. if err := ca.CreateTopic(v, &sarama.TopicDetail{NumPartitions: cfg.Consumer.Partition, ReplicationFactor: cfg.Consumer.Replication}, false); nil != err {
  144. panic(err)
  145. }
  146. log4go.Info("create topic ok", v)
  147. }
  148. }
  149. }
  150. }
  151.  
  152. // 显示Topic列表
  153. if detail, err := ca.ListTopics(); nil != err {
  154. log4go.Info("ListTopics error", err)
  155. } else {
  156. for k := range detail {
  157. log4go.Info("[%s] %+v", k, detail[k])
  158. }
  159. }
  160.  
  161. if err := ca.Close(); nil != err {
  162. panic(err)
  163. }
  164.  
  165. return true
  166. }
  167. return false
  168. }
  169.  
  170. type Consumer struct {
  171. }
  172.  
  173. func (consumer *Consumer) Setup(s sarama.ConsumerGroupSession) error {
  174. return nil
  175. }
  176.  
  177. func (consumer *Consumer) Cleanup(s sarama.ConsumerGroupSession) error {
  178. return nil
  179. }
  180.  
  181. func (consumer *Consumer) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
  182. for message := range claim.Messages() {
  183. key := string(message.Key)
  184. val := string(message.Value)
  185. log4go.Info("%s-%s", key, val)
  186. session.MarkMessage(message, "")
  187. }
  188.  
  189. return nil
  190. }

[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. javascript中的onmousewheel事件处理

    滚轮事件在不同浏览器会有一点点区别,一个像Firefox使用DOMMouseScroll ,FF也可以使用addEventListener方法绑定DomMouseScroll事件,其他的浏览器滚轮事件 ...

  2. 做了一个动态代理IP池项目,邀请大家免费测试~

    现在出来创业了,目前公司在深圳. 做了啥呢, 做了一个动态代理 IP 池项目 现在邀请大家免费测试体验! 免费激活码:关注微信公众号:2808proxy (每人每天限领一次噢~) 网站:https:/ ...

  3. OUTLOOK - Unable to Delete Meetings

    Error Information: Resolved: Check Meeting room permission.Get-MailboxFolderPermission MeetingRoom_1 ...

  4. srs2.0安装问题

    原文: https://blog.csdn.net/ddr77/article/details/52511340 编译配置如下 ./configure --disable-all --with-ssl ...

  5. Execution failed for task ':compileDebugAidl'.

    昨天终于升级了下Ubuntu系统到16.04LTS,之前是12.04LTS(导致内网一些同事开发的网址无法打开,以及其他工具软件无法安装). 安装完android开发工具,运行之前的project,出 ...

  6. ThunderBird对只有回复地址的邮件过滤

    回复地址,其实就是reply-to 增加一个自定义的字段:reply-to即可

  7. [Canvas]空战游戏进阶 增加爆炸管理类

    点此下载源码,欲观看效果请用Chrome打开index.html 图例: 源码: <!DOCTYPE html> <html lang="utf-8"> & ...

  8. Java驱动远程连接mongoDB(简明易懂版)

    mongodb默认是不能远程连接的,而且在linux安装完你会发现,它的目录极其简单,连个配置文件都没有. 我的mongodb的版本是3.6,目前最新的.https://www.mongodb.com ...

  9. Nop--NopCommerce源码架构详解专题目录

    最近在研究外国优秀的ASP.NET mvc电子商务网站系统NopCommerce源码架构.这个系统无论是代码组织结构.思想及分层都值得我们学习.对于没有一定开发经验的人要完全搞懂这个源码还是有一定的难 ...

  10. Effective Java 第三版——78. 同步访问共享的可变数据

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...