消息队列(Message Queue,简称MQ),指保存消息的一个容器,本质是个队列。许多人认为 MQ 通过消息的发送和接受来实现程序的异步和解耦,mq主要用于异步操作,这个不是 MQ 的真正目的,只不过是 MQ 的应用,MQ 真正的目的是为了通讯。
一、Kafka介绍
- Kafka 本质上是⼀个消息队列,一个高吞吐量、持久性、分布式的消息系统。
- 包含生产者(producer)和消费者(consumer),每个consumer属于一个特定的消费者组(Consumer Group)。
- 生产者生产消息(message)写入到kafka服务器(broker,kafka集群的节点),消费者从kafka服务器(broker)读取消息。
- 消息可分为不同的类型即不同的主题(topic)。
- 同一主题(topic)的消息可以分散存储到不同的服务器节点(partition)上,一个分区(partition)只能由一个消费者组内的一个消费者消费。
- 每个partition可以有多个副本,一个Leader和若干个Follower,Leader发生故障时,会选取某个Follower成为新的Leader。
二、kafka的安装(win端)
1、安装jdk环境,下载地址,然后根据解压或者安装目录配置jdk的环境变量,这里不再详细介绍
2、kafka下载安装,下载地址,我这里选择 kafka_2.13-3.5.1,由于kafka里面自带了zookeeper,所以我们不需要单独去下载zookeeper
3、解压kafka至合适目录,然后编辑 \kafka_2.13-3.5.1\config 里面的配置文件
- 首先编辑
zookeeper.properties文件 修改里面的dataDir为dataDir=D:\kafka\kafka_2.13-3.5.1\zookeeper目录根据实际情况来修改,然后在文件最后添加audit.enable=true - 然后编辑
server.properties文件,修改log.dirs 为log.dirs=D:\kafka\kafka_2.13-3.5.1\kafka-logs目录也是根据实际情况修改
4、配置文件修改完成后,首先启动 zookeeper,需要回到 kafka 的安装目录,然后在cmd中执行:
.\bin\windows\zookeeper-server-start.bat .\config\zookeeper.properties
5、zookeeper 启动成功后,接下来启动 kafka,在cmd中执行:
.\bin\windows\kafka-server-start.bat .\config\server.properties
6、Kafka的默认端口是9092,用于在Kafka Broker之间传输消息。使用TCP协议,客户端通过连接Broker的IP地址和端口号,发送请求和接收返回的消息。
三、go连接kafka
1、安装kafka驱动
go get github.com/segmentio/kafka-go
2、使用生产者代码发送信息
下面代码实现了模拟生产者向kafka发送消息的过程
我们首先创建了一个sarama的配置对象"config"。设置了生产者的一些属性,例如"RequiredAcks"表示发送完数据需要等待leader和follow都确认;"Partitioner"表示新选出一个partition;"Return.Successes"为true表示成功交付的消息将在success channel返回。
然后,构造了一个ProducerMessage对象"msg",设置了要发送的消息的topic和value。
接着,使用NewSyncProducer方法创建了一个同步生产者"client",并传入Kafka broker的地址以及之前创建的配置对象。如果出现错误,会打印错误信息并退出程序。最后,使用SendMessage方法发送消息,并返回发送的分区号(pid)、消息在分区中的偏移量(offset)以及可能的错误信息(err)。
最后,打印发送结果(pid和offset),并在结束时关闭生产者连接。
package main
import (
"fmt"
"github.com/Shopify/sarama"
)
// 基于sarama第三方库开发的kafka client
func main() {
config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForAll // 发送完数据需要leader和follow都确认
config.Producer.Partitioner = sarama.NewRandomPartitioner // 新选出一个partition
config.Producer.Return.Successes = true // 成功交付的消息将在success channel返回
// 构造一个消息
msg := &sarama.ProducerMessage{}
msg.Topic = "web_log"
msg.Value = sarama.StringEncoder("this is a test log")
// 连接kafka
client, err := sarama.NewSyncProducer([]string{"127.0.0.1:9092"}, config)
if err != nil {
fmt.Println("producer closed, err:", err)
return
}
defer client.Close()
// 发送消息
pid, offset, err := client.SendMessage(msg)
if err != nil {
fmt.Println("send msg failed, err:", err)
return
}
fmt.Printf("pid:%v offset:%v\n", pid, offset)
}
3、查看生产者发送的消息
使用kafka自带的命令行消费者客户端查看kafka中的数据,在kafka目录下打开cmd,输入下面命令,这里的 topic 和代码中的topic一致,均为 web_log,运行目录后可以看到输出了之前我们在代码中定义的字符串 "this is a test log"
.\bin\windows\kafka-console-consumer.bat --bootstrap-server 127.0.0.1:9092 --topic web_log --from-beginning
4、使用消费者代码获取消息
首先创建了一个sarama的配置对象"config",并设置"Return.Errors"为true以便处理消费错误。
然后,使用NewConsumer方法创建了一个消费者"consumer",并传入Kafka broker的地址以及配置对象。如果创建失败,将打印错误信息并退出程序。在函数结束时,记得关闭消费者连接。
接下来,指定要消费的topic和分区,并使用ConsumePartition方法创建一个分区消费者"partitionConsumer"。如果创建失败,同样会打印错误信息并退出程序。在函数结束时,也要关闭分区消费者连接。
最后,通过循环从分区消费者的Messages通道中读取消息,并打印出消息的key和value。同时,在处理完所有消息后,还需要检查是否有消费错误,如果有则打印错误信息。
package main
import (
"fmt"
"github.com/Shopify/sarama"
)
// 基于sarama第三方库开发的kafka client
func main() {
config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForAll // 发送完数据需要leader和follow都确认
config.Producer.Partitioner = sarama.NewRandomPartitioner // 新选出一个partition
config.Producer.Return.Successes = true // 成功交付的消息将在success channel返回
// 构造一个消息
msg := &sarama.ProducerMessage{}
msg.Topic = "web_log"
msg.Value = sarama.StringEncoder("this is a test log")
// 连接kafka
client, err := sarama.NewSyncProducer([]string{"127.0.0.1:9092"}, config)
if err != nil {
fmt.Println("producer closed, err:", err)
return
}
defer client.Close()
// 发送消息
pid, offset, err := client.SendMessage(msg)
if err != nil {
fmt.Println("send msg failed, err:", err)
return
}
fmt.Printf("pid:%v offset:%v\n", pid, offset)
}
运行结果